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; } } |