Java多線程Master-Worker模式

來源:互聯網
上載者:User

標籤:link   min   nts   value   protected   mem   entryset   prot   interrupt   

Java多線程Master-Worker模式,多適用於需要大量重複工作的情境中。

例如:使用Master-Worker計算0到100所有數位立方的和

  1.Master接收到100個任務,每個任務需要0到100中每個數位立方,這裡為了效果,每個任務再sleep一秒,

   Master需要將這些任務放到一個支援高並發的非阻塞隊列queue中如:ConcurrentLinkedQueue<E>。

  2.Master建立10個worker去執行這100個任務,並準備一個支援高並發且安全執行緒的hashMap作為結果集的容器如:ConcurrentHashMap。

  3.每個worker需要迴圈的從queue中擷取任務然後執行,執行完畢後把結果放到hashMap中,直到queue為空白,所有任務執行完畢後退出。

  4.Master迴圈判斷結果集hashMap中是否有已經執行完畢的結果,如果有就使用,使用完畢就立即移除該結果,直到所有的線程都退出。

  5.所有任務執行完畢,Master也處理完所有任務的結果,程式結束

Master不需要等待所有的任務執行完畢就可以處理已完成的任務結果,Master和worker可以同時進行工作,這樣節省了大量等待worker執行結束的時間

 

Master源碼

package masterWorker;import java.lang.Thread.State;import java.util.Collection;import java.util.HashMap;import java.util.Map;import java.util.Map.Entry;import java.util.Queue;import java.util.Set;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentLinkedQueue;import org.junit.Test;public class Master {public static void main(String[] args) {long befor = System.currentTimeMillis();//任務隊列Queue<Integer> taskQueue = new ConcurrentLinkedQueue<>();//工人mapMap<String,Thread> workers = new HashMap<>();//結果集Map<String,Long> resultMap = new ConcurrentHashMap<>();//最終結果long result = 0;//提交100個任務for (int i = 0; i < 100; i++) {taskQueue.add(i);}//添加10個工人for (int i = 0; i < 10; i++) {workers.put(i+"", new Thread(new Worker(taskQueue,resultMap),"工人"+i));}//啟動所有工人線程Collection<Thread> threads = workers.values();for (Thread thread : threads) {thread.start();}while(resultMap.size() > 0 || !isComplete(workers)){Set<String> keySet = resultMap.keySet();//每次從resultMap中取一個結果出來進行使用String key = null;for (String string : keySet) {if(string != null){key = string;break;}}Long value = null;if(key != null){value = resultMap.get(key);}//能取到結果就使用,沒有結果繼續迴圈if(value != null){//擷取到一個運算結果就使用result = result+value;//使用後從結果集中移除resultMap.remove(key);}}long after = System.currentTimeMillis();System.out.println("結果耗時:"+(after - befor));System.out.println(result);}/** * 判斷所有的工人是否已經完成工作 * @param workers * @return */private static boolean isComplete(Map<String,Thread> workers){for (Entry<String, Thread> entry : workers.entrySet()) {if(entry.getValue().getState() != State.TERMINATED){return false;}}return true;}@Testpublic void test() throws InterruptedException{long befor = System.currentTimeMillis();long result = 0;for (int i = 0; i < 100; i++) {long cube = i*i*i;result = result+cube;Thread.sleep(100);}long after = System.currentTimeMillis();System.out.println("結果耗時:"+(after - befor));System.out.println(result);}}

  

  

Worker源碼

package masterWorker;import java.util.Map;import java.util.Queue;public class Worker implements Runnable{private Queue<Integer> queue;private Map<String,Long> resultMap;public Worker(Queue<Integer> queue,Map<String,Long> resultMap) {this.queue = queue;this.resultMap = resultMap;}@Overridepublic void run() {//不斷迴圈從隊列中取出任務進行運算,直到隊列為空白while(true){if(queue.peek() != null){String name = Thread.currentThread().getName();int poll =(int) queue.poll();long result = poll*poll*poll;try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}resultMap.put(poll+"", result);System.out.println(name+"完成"+poll+"的運算,結果為:"+result);}else{break;}}}}

  

經典的Master-Worker源碼執行個體

package masterWorker.classics;import java.util.Map;  import java.util.Set;    public class Main {              /**      * @param args      */      public static void main(String[] args) {          //固定使用5個Worker,並指定Worker          Master m = new Master(new PlusWorker(), Runtime.getRuntime().availableProcessors());          //提交100個子任務          for(int i=0;i<100;i++){              m.submit(i);          }          //開始計算          m.execute();          int re= 0;          //儲存最終結算結果          Map<String ,Object> resultMap =m.getResultMap();                    //不需要等待所有Worker都執行完成,即可開始計算最終結果          while(resultMap.size()>0 || !m.isComplete()){              Set<String> keys = resultMap.keySet();              String key =null;              for(String k:keys){                  key=k;                  break;              }              Integer i =null;              if(key!=null){                  i=(Integer)resultMap.get(key);              }              if(i!=null){                  //最終結果                  re+=i;              }              if(key!=null){                  //移除已經被計算過的項                  resultMap.remove(key);              }                        }          System.out.println(re);    }    }  package masterWorker.classics;import java.util.Map;  import java.util.Queue;    public class Worker  implements Runnable{        //任務隊列,用於取得子任務      protected Queue<Object> workQueue;      //子任務處理結果集      protected Map<String ,Object> resultMap;      public void setWorkQueue(Queue<Object> workQueue){          this.workQueue= workQueue;      }            public void setResultMap(Map<String ,Object> resultMap){          this.resultMap=resultMap;      }      //子任務處理的邏輯,在子類中實現具體邏輯      public Object handle(Object input){          return input;      }                  @Override      public void run() {                    while(true){              //擷取子任務              Object input= workQueue.poll();              if(input==null){                  break;              }              //處理子任務              Object re = handle(input);              resultMap.put(Integer.toString(input.hashCode()), re);          }      }    }  package masterWorker.classics;public class PlusWorker extends Worker {        @Override      public Object handle(Object input) {                    Integer i =(Integer)input;          return i*i*i;      }          }  package masterWorker.classics;import java.util.HashMap;import java.util.Map;import java.util.Queue;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentLinkedQueue;public class Master {// 任務隊列protected Queue<Object> workQueue = new ConcurrentLinkedQueue<Object>();// Worker進程隊列protected Map<String, Thread> threadMap = new HashMap<String, Thread>();// 子任務處理結果集protected Map<String, Object> resultMap = new ConcurrentHashMap<String, Object>();// 是否所有的子任務都結束了public boolean isComplete() {for (Map.Entry<String, Thread> entry : threadMap.entrySet()) {if (entry.getValue().getState() != Thread.State.TERMINATED) {return false;}}return true;}// Master的構造,需要一個Worker進程邏輯,和需要Worker進程數量public Master(Worker worker, int countWorker) {worker.setWorkQueue(workQueue);worker.setResultMap(resultMap);for (int i = 0; i < countWorker; i++) {threadMap.put(Integer.toString(i),new Thread(worker, Integer.toString(i)));}}// 提交一個任務public void submit(Object job) {workQueue.add(job);}// 返回子任務結果集public Map<String, Object> getResultMap() {return resultMap;}// 開始運行所有的Worker進程,進行處理public void execute() {for (Map.Entry<String, Thread> entry : threadMap.entrySet()) {entry.getValue().start();}}}

  

 

Java多線程Master-Worker模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.