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

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進程不需要等待所有子任務都完成,就可以根據已有的部分結果集計算最終結果。

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