【问题标题】:How to return messages from child threads to main thread(method) in Java?如何在Java中将消息从子线程返回到主线程(方法)?
【发布时间】:2020-06-14 06:53:33
【问题描述】:

我有一个想要互相交流的人的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 类将为 HashMap 中的每个键迭代地创建一个线程。请注意readFile 方法只会从文本文件中读取并生成我上面提到的输入(到callsMap 变量中)。这对于这个上下文不是特别重要,所以我在这里省略了它。

我有 SubTasks 类,它扩展了 Thread 类并为每次交互创建消息。这个类不会创建任何额外的线程,只是对它收到的调用者和接收者列表进行操作,如下所示:

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 方法。

【问题讨论】:

    标签: java multithreading parallel-processing java-threads


    【解决方案1】:

    我建议你在你的用例中使用Executor框架Callable接口和Futures,因为你需要的一切都已经解决了。重写课程将帮助您正确解决它。

         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;
                }
            }
        }
    

    【讨论】:

    • 我需要将两个语句从单个线程返回到主函数。我怎样才能做到这一点?因为调用函数只能返回一条语句。
    猜你喜欢
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多