Master-Worker模式是一種使用多線程進行數據處理的結構。多個Worker進程協作處理用戶請求,Master進程負責維護Worker進程,並整合最終處理結果。
概念
Master-Worker模式是常用的並行模式之一。系統有兩類進程協作工作:Master進程和Worker進程。Master進程負責接收和分配任務,Worker進程負責處理子任務。當所有的Worker進程將子任務完成以後,將結果返回給Master進程,由Master進程做歸納和總結。
工作示意圖
模式結構圖
Master維護任務隊列、Worker進程隊列、子任務結果集
代碼實現
Master-Worker模式簡易實現
Master
public class Master{
//任務隊列
protected Queue<Object> taskQueue=new ConcurrentLinkedQueue<>();
//子任務結果集
protected Map<String ,Object> resultMap=new HashMap<>();
//worker進程隊列
protected Map<String ,Thread> threadMap=new HashMap<>();
//判斷所有的子任務是否都結束
public boolean isComeplete(){
for (Map.Entry<String,Thread> entry:threadMap.entrySet()){
if (entry.getValue().getState()!= Thread.State.TERMINATED){
return false;
}
}
return true;
}
public Master(Worker worker,int countWorker){
worker.setWorkQueue(taskQueue);
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 o){
taskQueue.add(o);
}
//返回子任務結果集
public Map<String ,Object> getResultMap(){
return resultMap;
}
//開始運行所有的worker進程
public void execute(){
for (Map.Entry<String,Thread> entry:threadMap.entrySet()){
entry.getValue().start();
}
}
}
Worker
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);
}
}
}
實戰
計算100以內的數字的立方和
CubePlusWorker
public class CubePlusWorker extends Worker {
//子任務具體實現邏輯
@Override
public Object handle(Object input) {
Integer integer=Integer.valueOf(input.toString());
return integer*integer*integer;
}
}
Main
public class Main {
public static void main(String[] args) {
long s=System.nanoTime();
CubePlusWorker cube = new CubePlusWorker();
Master master = new Master(cube, 10);
//分解爲100個子任務
for (int i = 1; i <= 100; i++) {
master.submit(i);
}
//執行子任務
master.execute();
Integer result = 0;
System.out.println("每個子任務的執行結果是:");
for (Map.Entry<String, Object> entry : master.getResultMap().entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
result += Integer.valueOf(entry.getValue().toString());
}
System.out.println("開始彙總計算結果:");
if (result != 0 && master.isComeplete()) {
System.out.println("The SUM is : " + result);
}
System.out.println("Cost time :"+(System.nanoTime()-s)+"ns");
}
}
執行結果:
開始彙總計算結果:
The SUM is : 17236269
Cost time :3900697ns
不使用Master-Worker模式的程序執行時間要比這個快很多。
實戰優化
優化計算代碼。不需要等待所有Worker都執行完,即可開始計算最終結果。
public class Main {
public static void main(String[] args) {
long s = System.nanoTime();
Master master=new Master(new CubePlusWorker(),10);
for(int i=1;i<=100;i++){
master.submit(i);
}
master.execute();
Map<String,Object> resultMap=master.getResultMap();
int result=0;
while (resultMap.size()>0 || !master.isComeplete()){
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){
result+=i;
}
//移除已被計算過的
if (key!=null){
resultMap.remove(key);
}
}
System.out.println("The SUM is : " + result);
System.out.println("Cost time :" + (System.nanoTime() - s) + "ns");
}
}
Master-Worker模式是一種將串行任務並行化的方法,被分解的子任務在系統中可以被並行處理。同時,Master進程不需要等待所有子任務都完成,就可以根據已有的部分結果集計算最終結果。