Master-Worker模式
/** * Master-Wroker模式:這也是常用的並行模式,核心思想是系統由Master和Worker兩類進行協同工作。 * Master負責接收和分配任務,Worker負責處理子任務,但各個Worker子進程處理完成後,會將結果返回給Master,由Master歸納和總結。 * 好處就是能將一個大任務分解成爲若干個小任務並行執行,從而提高系統的吞吐量。 * 現有框架設計:Hadoop、Spark */ public class C04MasterWorker { public static void main(String[] args) {
//設置N個Worker同時執行 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; } }
/* * 1、Master在初始化時,就生成好對應數量的Worker了,並放在容器中。 * 1.1、Worker會有Master的Task併發存儲容器的引用和併發結果容器存放的引用,讓Worker可以獲取到任務和存放執行結果。 * 2、在提交Task時,由於Worker是併發執行的,所以每一個Task也是存放在併發容器中的。 * 3、調用Master執行方法時,則取出Worker容器中的每一個Worker,啓動該線程去執行任務。 * 3.1、每一個Worker線程會取出Master的Task併發存儲容器中的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; } } |