簡體   English   中英

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擴展了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 對打印消息,我會得到所需的 output。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM