Java設計模式(4) - 多線程併發設計模式 - Master-Worker設計模式

Master-Worker模式

/**

 * Master-Wroker模式:這也是常用的並行模式,核心思想是系統由MasterWorker兩類進行協同工作。

 * Master負責接收和分配任務,Worker負責處理子任務,但各個Worker子進程處理完成後,會將結果返回給Master,由Master歸納和總結。

 * 好處就是能將一個大任務分解成爲若干個小任務並行執行,從而提高系統的吞吐量。

 * 現有框架設計:HadoopSpark

 */

public class C04MasterWorker {

    public static void main(String[] args) {

        

         //設置NWorker同時執行

         Master master = new Master(100);

        

         //提交100個任務給master

         for (int i = 0; i < 100; i++) {

             master.submitTask(new Task(i,i + " " + "Test"));

         }

        

         //開始執行

         master.execute();

        

         long startTime = System.currentTimeMillis();

        

         while (true) {

             if(master.isComplete()) {

                  long endTime = System.currentTimeMillis();

                 System.out.println("結果:" + master.getResult().size());

                  System.out.println("運行時間:" + (endTime - startTime));

                  break;

             }

         }

        

         /*

          * 1Master在初始化時,就生成好對應數量的Worker了,並放在容器中。

          * 1.1Worker會有MasterTask併發存儲容器的引用和併發結果容器存放的引用,讓Worker可以獲取到任務和存放執行結果。

          * 2、在提交Task時,由於Worker是併發執行的,所以每一個Task也是存放在併發容器中的。

          * 3、調用Master執行方法時,則取出Worker容器中的每一個Worker,啓動該線程去執行任務。

          * 3.1、每一個Worker線程會取出MasterTask併發存儲容器中的Task去執行,執行完一個則取出下一個,取的方法是取出後在容器刪除這個Task,避免重複執行。

          */

        

    }

}

/**

 * 負責接收和分配任務,並收集所有Worker處理的結果

 */

class Master {

   

    //存放任務容器

    private ConcurrentLinkedQueue<Task> workerTasks = new ConcurrentLinkedQueue<>();

   

    //存放執行的Worker(併發執行)

    private Map<String, Thread> workers = new HashMap<>();

   

    //存放Worker執行結果(併發執行)

    private ConcurrentHashMap<String, Object> result = new ConcurrentHashMap<>();

 

    /**

     * 初始化Master時,也初始化出對應數量的Worker

     * @param worker Worker

     * @param workerCount

     */

    public Master(int workerCount) {

         //將容器引用設置過去給Worker

         Worker worker = new Worker();

         worker.setWorkerTasks(workerTasks);

         worker.setResult(result);

        

         for (int i = 0; i < workerCount; i++) {

             this.workers.put(i + "", new Thread(worker));

         }

    }

   

    /**

     * 初始化完成對應的Worker之後,要能讓用戶提交Task,在將Task分配給對應的Worker去執行

     * @param task

     * @return boolean

     */

    public boolean submitTask(Task task) {

         return this.workerTasks.add(task);

    }

   

    /**

     * 提交完成任務後,要讓Workers去執行任務

     * @return boolean

     */

    public boolean execute() {

         for (Entry<String, Thread> entry : workers.entrySet()) {

             entry.getValue().start();

         }

         return true;

    }

   

    /**

     * 所有任務是否已經運行完成

     * @return boolean

     */

    public boolean isComplete() {

         for (Entry<String, Thread> entry : workers.entrySet()) {

             if (entry.getValue().getState() != Thread.State.TERMINATED) {

                  return false;

             }

         }

         return true;

    }

   

    /**

     * 獲取到執行結果

     * @return List<Object>

     */

    public List<Object> getResult() {

         List<Object> result = new ArrayList<>();

         for (Entry<String, Object> entry : this.result.entrySet()) {

             result.add(entry.getValue());

         }

         return result;

    }

   

}

/**

 * 具體處理任務

 */

class Worker implements Runnable {

   

    //Master分配過來,要執行的任務

    private ConcurrentLinkedQueue<Task> workerTasks;

   

    //執行的結果

    private ConcurrentHashMap<String, Object> result;

 

    public void setWorkerTasks(ConcurrentLinkedQueue<Task> workerTasks) {

         this.workerTasks = workerTasks;

    }

 

    public void setResult(ConcurrentHashMap<String, Object> result) {

         this.result = result;

    }

 

    /*

     * 多線程執行分配到的任務

     */

    @Override

    public void run() {

         while (true) {

             Task task = this.workerTasks.poll();

             if (null == task) {

                  break;

             }

             //任務處理,並把處理結果放到容器中

             Object handleResult = handle(task);

             this.result.put(task.getId().toString(), handleResult);

         }

    }

   

    /**

     * 模擬任務處理邏輯

     */

    private Object handle(Task task) {

         try {

             Thread.sleep(300);

         } catch (InterruptedException e) {

             e.printStackTrace();

         }

         String desc = task.getDesc();

         return desc;

    }

   

}

/**

 * 任務

 */

class Task {

   

    private Integer id;

   

    private String desc;

 

    public Task(Integer id, String desc) {

         super();

         this.id = id;

         this.desc = desc;

    }

 

    public Integer getId() {

         return id;

    }

 

    public void setId(Integer id) {

         this.id = id;

    }

 

    public String getDesc() {

         return desc;

    }

 

    public void setDesc(String desc) {

         this.desc = desc;

    }

}

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