併發模型(二)——Master-Worker模式

轉載:http://blog.csdn.net/lmdcszh/article/details/39698189

aster-Worker模式是常用的並行模式之一,它的核心思想是,系統有兩個進程協作工作:Master進程,負責接收和分配任務;Worker進程,負責處理子任務。當Worker進程將子任務處理完成後,結果返回給Master進程,由Master進程做歸納彙總,最後得到最終的結果。

一、什麼是Master-Worker模式:

該模式的結構圖:

  結構圖:


Worker:用於實際處理一個任務;

Master:任務的分配和最終結果的合成;

Main:啓動程序,調度開啓Master。


二、代碼實現:

    下面的是一個簡易的Master-Worker框架實現。

(1)Master部分:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package MasterWorker;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5. import java.util.Queue;  
  6. import java.util.concurrent.ConcurrentHashMap;  
  7. import java.util.concurrent.ConcurrentLinkedQueue;  
  8.   
  9. public class Master {  
  10.   
  11.     //任務隊列  
  12.     protected Queue<Object> workQueue= new ConcurrentLinkedQueue<Object>();  
  13.     //Worker進程隊列  
  14.     protected Map<String ,Thread> threadMap= new HashMap<String ,Thread>();  
  15.     //子任務處理結果集  
  16.     protected Map<String ,Object> resultMap= new ConcurrentHashMap<String, Object>();  
  17.     //是否所有的子任務都結束了  
  18.     public boolean isComplete(){  
  19.         for(Map.Entry<String , Thread> entry:threadMap.entrySet()){  
  20.             if(entry.getValue().getState()!=Thread.State.TERMINATED){  
  21.                 return false;  
  22.             }  
  23.                   
  24.         }  
  25.         return true ;  
  26.     }  
  27.       
  28.     //Master的構造,需要一個Worker進程邏輯,和需要Worker進程數量  
  29.     public Master(Worker worker,int countWorker){  
  30.           
  31.         worker.setWorkQueue(workQueue);  
  32.         worker.setResultMap(resultMap);  
  33.         for(int i=0;i<countWorker;i++){  
  34.             threadMap.put(Integer.toString(i),  new Thread(worker, Integer.toString(i)));  
  35.         }  
  36.           
  37.     }  
  38.       
  39.     //提交一個任務  
  40.     public void submit(Object job){  
  41.         workQueue.add(job);  
  42.     }  
  43.       
  44.       
  45.     //返回子任務結果集  
  46.     public Map<String ,Object> getResultMap(){  
  47.         return resultMap;  
  48.     }  
  49.       
  50.       
  51.     //開始運行所有的Worker進程,進行處理  
  52.     public  void execute(){  
  53.          for(Map.Entry<String , Thread> entry:threadMap.entrySet()){  
  54.              entry.getValue().start();  
  55.                
  56.          }  
  57.     }  
  58.       
  59.       
  60. }  

(2)Worker進程實現:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package MasterWorker;  
  2.   
  3. import java.util.Map;  
  4. import java.util.Queue;  
  5.   
  6. public class Worker  implements Runnable{  
  7.   
  8.     //任務隊列,用於取得子任務  
  9.     protected Queue<Object> workQueue;  
  10.     //子任務處理結果集  
  11.     protected Map<String ,Object> resultMap;  
  12.     public void setWorkQueue(Queue<Object> workQueue){  
  13.         this.workQueue= workQueue;  
  14.     }  
  15.       
  16.     public void setResultMap(Map<String ,Object> resultMap){  
  17.         this.resultMap=resultMap;  
  18.     }  
  19.     //子任務處理的邏輯,在子類中實現具體邏輯  
  20.     public Object handle(Object input){  
  21.         return input;  
  22.     }  
  23.       
  24.       
  25.     @Override  
  26.     public void run() {  
  27.           
  28.         while(true){  
  29.             //獲取子任務  
  30.             Object input= workQueue.poll();  
  31.             if(input==null){  
  32.                 break;  
  33.             }  
  34.             //處理子任務  
  35.             Object re = handle(input);  
  36.             resultMap.put(Integer.toString(input.hashCode()), re);  
  37.         }  
  38.     }  
  39.   
  40. }  

(3)運用這個小框架計算1——100的立方和,PlusWorker的實現:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package MasterWorker;  
  2.   
  3. public class PlusWorker extends Worker {  
  4.   
  5.     @Override  
  6.     public Object handle(Object input) {  
  7.           
  8.         Integer i =(Integer)input;  
  9.         return i*i*i;  
  10.     }  
  11.   
  12.       
  13. }  

(4)進行計算的Main函數:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package MasterWorker;  
  2.   
  3. import java.util.Map;  
  4. import java.util.Set;  
  5.   
  6. public class Main {  
  7.   
  8.       
  9.     /** 
  10.      * @param args 
  11.      */  
  12.     public static void main(String[] args) {  
  13.         //固定使用5個Worker,並指定Worker  
  14.         Master m = new Master(new PlusWorker(), 5);  
  15.         //提交100個子任務  
  16.         for(int i=0;i<100;i++){  
  17.             m.submit(i);  
  18.         }  
  19.         //開始計算  
  20.         m.execute();  
  21.         int re= 0;  
  22.         //保存最終結算結果  
  23.         Map<String ,Object> resultMap =m.getResultMap();  
  24.           
  25.         //不需要等待所有Worker都執行完成,即可開始計算最終結果  
  26.         while(resultMap.size()>0 || !m.isComplete()){  
  27.             Set<String> keys = resultMap.keySet();  
  28.             String key =null;  
  29.             for(String k:keys){  
  30.                 key=k;  
  31.                 break;  
  32.             }  
  33.             Integer i =null;  
  34.             if(key!=null){  
  35.                 i=(Integer)resultMap.get(key);  
  36.             }  
  37.             if(i!=null){  
  38.                 //最終結果  
  39.                 re+=i;  
  40.             }  
  41.             if(key!=null){  
  42.                 //移除已經被計算過的項  
  43.                 resultMap.remove(key);  
  44.             }  
  45.               
  46.         }  
  47.           
  48.   
  49.     }  
  50.   
  51. }  

三、總結:

    Master-Worker模式是一種將串行任務並行化的方案,被分解的子任務在系統中可以被並行處理,同時,如果有需要,Master進程不需要等待所有子任務都完成計算,就可以根據已有的部分結果集計算最終結果集。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章