return 如何在 Java 中从子线程向主线程(方法)发送消息?
How to return messages from child threads to main thread(method) in Java?
我有一个人的HashMap,想互相交流如下:
{zidane=[rooney, rooney, rooney, scholes, rooney], rooney=[scholes, messi, scholes], scholes=[ronaldo], ronaldo=[rooney, messi, scholes], messi=[zidane]}
在这里,密钥中的每个人都有自己的线程,他们将在其中向列表中的每个人发送消息并收到回复。
import java.util.*;
public class Master {
public Map callsMap = new HashMap<String, List>();
public static void main(String[] args){
Master m = new Master();
m.readFile();
Iterator<Map.Entry<String, List>> it = m.callsMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, List> pair = it.next();
String caller = pair.getKey();
List receiverList = pair.getValue();
SubTasks st = new SubTasks(caller, receiverList);
Thread thread = new Thread(st);
thread.start();
//st.getMessage();
}
}
}
master
class 将迭代地为 HashMap 中的每个键创建一个线程。请注意,readFile
方法只会从文本文件中读取并生成我上面提到的输入(到 callsMap
变量中)。这对这个上下文来说不是特别重要,所以我在这里省略了它。
我有 SubTasks
class 扩展 Thread
class 并为每次交互创建消息。这个 class 不会创建任何额外的线程,而只是对它收到的调用者和接收者列表进行操作,如下所示:
import java.util.List;
public class SubTasks extends Thread {
private String caller;
private List receiverList;
private volatile String returnMessage;
SubTasks(String s, List l){
caller = s;
receiverList = l;
}
public void setMessage(String msg){
returnMessage = msg;
}
public String getMessage() {
return returnMessage;
}
@Override
public void run(){
for (int i = 0; i < receiverList.size(); i++) {
System.out.println(receiverList.get(i)+" received intro message from "+caller +" ["+System.currentTimeMillis()+"]");
returnMessage = caller+" received reply message from "+receiverList.get(i) +" ["+System.currentTimeMillis()+"]";
//setMessage(returnMessage);
System.out.println(returnMessage);
}
}
}
如果我在所有 26 对的子线程中打印消息,我将获得所需的输出。
zidane received message from messi [1592117172946]
rooney received message from ronaldo [1592117172946]
scholes received message from rooney [1592117172946]
rooney received message from zidane [1592117172946]
ronaldo received message from scholes [1592117172946]
messi received reply from zidane [1592117172989]
ronaldo received reply from rooney [1592117172989]
...
...
如何将这些消息传递到主线程(方法)并在那里打印而不是子线程?我尝试使用 getter-setter
方法,但由于线程将随机执行,因此无法正确调用 getter
方法。
我建议你在用例中使用 Executor
框架 Callable
接口和 Futures
,因为你需要的一切都已经解决了。重写 class 将帮助您正确解决它。
public class Master {
public Map callsMap = new HashMap<String, List>();
public static void main(String[] args){
Master m = new Master();
m.readFile();
ExecutorService executorService = Executors.newFixedThreadPool(10);// or some desired number
List<Future<String>> returnFutures = new ArrayList<>();
Iterator<Map.Entry<String, List>> it = m.callsMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, List> pair = it.next();
String caller = pair.getKey();
List receiverList = pair.getValue();
returnFutures.add(executorService.submit(new SubTasks(caller, receiverList) ));
}
executorService.shutdown();
while(executorService.awaitTermination(1000, TimeUnit.SECONDS));
for(Future<String> returnFuture: returnFutures){
/* returnFuture.get() will have the returned value from the thread, if the thread has completed execution,
otherwise it will wait for the completion*/
System.out.println(returnFuture.get());
}
}
}
和
public class SubTasks implements Callable<String> {
private String caller;
private List receiverList;
private volatile String returnMessage;
SubTasks(String s, List l){
caller = s;
receiverList = l;
}
public void setMessage(String msg){
returnMessage = msg;
}
public String getMessage() {
return returnMessage;
}
@Override
public String call (){
for (int i = 0; i < receiverList.size(); i++) {
System.out.println(receiverList.get(i)+" received intro message from "+caller +" ["+System.currentTimeMillis()+"]");
returnMessage = caller+" received reply message from "+receiverList.get(i) +" ["+System.currentTimeMillis()+"]";
return returnMessage;
}
}
}
我有一个人的HashMap,想互相交流如下:
{zidane=[rooney, rooney, rooney, scholes, rooney], rooney=[scholes, messi, scholes], scholes=[ronaldo], ronaldo=[rooney, messi, scholes], messi=[zidane]}
在这里,密钥中的每个人都有自己的线程,他们将在其中向列表中的每个人发送消息并收到回复。
import java.util.*;
public class Master {
public Map callsMap = new HashMap<String, List>();
public static void main(String[] args){
Master m = new Master();
m.readFile();
Iterator<Map.Entry<String, List>> it = m.callsMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, List> pair = it.next();
String caller = pair.getKey();
List receiverList = pair.getValue();
SubTasks st = new SubTasks(caller, receiverList);
Thread thread = new Thread(st);
thread.start();
//st.getMessage();
}
}
}
master
class 将迭代地为 HashMap 中的每个键创建一个线程。请注意,readFile
方法只会从文本文件中读取并生成我上面提到的输入(到 callsMap
变量中)。这对这个上下文来说不是特别重要,所以我在这里省略了它。
我有 SubTasks
class 扩展 Thread
class 并为每次交互创建消息。这个 class 不会创建任何额外的线程,而只是对它收到的调用者和接收者列表进行操作,如下所示:
import java.util.List;
public class SubTasks extends Thread {
private String caller;
private List receiverList;
private volatile String returnMessage;
SubTasks(String s, List l){
caller = s;
receiverList = l;
}
public void setMessage(String msg){
returnMessage = msg;
}
public String getMessage() {
return returnMessage;
}
@Override
public void run(){
for (int i = 0; i < receiverList.size(); i++) {
System.out.println(receiverList.get(i)+" received intro message from "+caller +" ["+System.currentTimeMillis()+"]");
returnMessage = caller+" received reply message from "+receiverList.get(i) +" ["+System.currentTimeMillis()+"]";
//setMessage(returnMessage);
System.out.println(returnMessage);
}
}
}
如果我在所有 26 对的子线程中打印消息,我将获得所需的输出。
zidane received message from messi [1592117172946]
rooney received message from ronaldo [1592117172946]
scholes received message from rooney [1592117172946]
rooney received message from zidane [1592117172946]
ronaldo received message from scholes [1592117172946]
messi received reply from zidane [1592117172989]
ronaldo received reply from rooney [1592117172989]
...
...
如何将这些消息传递到主线程(方法)并在那里打印而不是子线程?我尝试使用 getter-setter
方法,但由于线程将随机执行,因此无法正确调用 getter
方法。
我建议你在用例中使用 Executor
框架 Callable
接口和 Futures
,因为你需要的一切都已经解决了。重写 class 将帮助您正确解决它。
public class Master {
public Map callsMap = new HashMap<String, List>();
public static void main(String[] args){
Master m = new Master();
m.readFile();
ExecutorService executorService = Executors.newFixedThreadPool(10);// or some desired number
List<Future<String>> returnFutures = new ArrayList<>();
Iterator<Map.Entry<String, List>> it = m.callsMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, List> pair = it.next();
String caller = pair.getKey();
List receiverList = pair.getValue();
returnFutures.add(executorService.submit(new SubTasks(caller, receiverList) ));
}
executorService.shutdown();
while(executorService.awaitTermination(1000, TimeUnit.SECONDS));
for(Future<String> returnFuture: returnFutures){
/* returnFuture.get() will have the returned value from the thread, if the thread has completed execution,
otherwise it will wait for the completion*/
System.out.println(returnFuture.get());
}
}
}
和
public class SubTasks implements Callable<String> {
private String caller;
private List receiverList;
private volatile String returnMessage;
SubTasks(String s, List l){
caller = s;
receiverList = l;
}
public void setMessage(String msg){
returnMessage = msg;
}
public String getMessage() {
return returnMessage;
}
@Override
public String call (){
for (int i = 0; i < receiverList.size(); i++) {
System.out.println(receiverList.get(i)+" received intro message from "+caller +" ["+System.currentTimeMillis()+"]");
returnMessage = caller+" received reply message from "+receiverList.get(i) +" ["+System.currentTimeMillis()+"]";
return returnMessage;
}
}
}