Master-Worker设计模式是常用的并行的计算模式,它的核心思想是系统由两类进程协作工作:Master进程和Worker进程,Master负责接口和分配任务,Worker负责处理子任务,当各个Worker子进程处理完成后,会将结果返回给Master,由Master做归纳和汇总,其好处是将一个大任务分解成若干小任务,并行执行,从而提高了系统的吞吐量。
设计思路:
代码实现:
角色 | 作用 |
Master | 用于对总任务的拆分和汇总每一个worker的结果集 |
Worker | 处理每一个worker的任务 |
Main | 用于测试类,调用Master任务 |
Main方法:
public class Main {
public static void main(String[] args) {
Random random = new Random();
Master master = new Master(new Worker(),10);
for (int i = 1;i<100;i++) {
Task task = new Task();
task.setId(i);
task.setName("任务"+i);
task.setPrice(random.nextInt(1000));
master.submit(task);
}
master.exacute();
long begin = System.currentTimeMillis();
while (true) {
if (master.isComplate()) {
long end = System.currentTimeMillis() - begin;
int price = master.getResult();
System.out.println("最终结果:" + price + ",执行耗时:" + end);
break;
}
}
}
}
Master主任务实现:
/**
* 总任务Master
*/
public class Master {
//1.有一个承装元素的集合 ConcurrentLinkedQueue
private ConcurrentLinkedQueue<Task> workQueue = new ConcurrentLinkedQueue<Task>();
//2.使用普通的HashMap去承装所有的worker子任务
private HashMap<String,Thread> workers = new HashMap<String,Thread>();
//3.使用一个容器承装每一个worker并发执行的结果集
private ConcurrentHashMap<String,Object> resultMap = new ConcurrentHashMap<String,Object>();
//4.构造方法
public Master(Worker worker,int workCount) {
//每一个worker对象都需要Master的引用,workerQueue用于任务的领取,resultMap用于任务的提交
worker.setWorkerQueue(this.workQueue);
worker.setResultMap(this.resultMap);
for (int i = 0; i<workCount; i++) {
//key标识每一个worker的名字,value标识线程执行对象
workers.put("子节点" + Integer.toString(i),new Thread(worker));
}
}
//5.提交方法
public void submit(Task task) {
this.workQueue.add(task);
}
//6.需要一个执行的方法,用于启动应用程序,让所有的worker工作
public void exacute() {
for (Map.Entry<String,Thread> map : workers.entrySet()) {
map.getValue().start();
}
}
//7.判断线程是否执行完毕
public boolean isComplate() {
for (Map.Entry<String,Thread> map : workers.entrySet()) {
if (map.getValue().getState() != Thread.State.TERMINATED) {
return false;
}
}
return true;
}
//8.返回结果集数据
public int getResult() {
int ret = 0;
//把结果集的结果遍历返回
for (Map.Entry<String,Object> map : resultMap.entrySet()) {
//汇总结果
ret += (Integer)map.getValue();
}
return ret;
}
}
woker实现:
/**
* worker子任务
*/
public class Worker implements Runnable{
private ConcurrentLinkedQueue<Task> workQueue;
private ConcurrentHashMap<String, Object> resultMap;
public void setWorkerQueue(ConcurrentLinkedQueue<Task> workQueue) {
this.workQueue = workQueue;
}
public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
this.resultMap = resultMap;
}
@Override
public void run() {
while (true) {
//移除已经执行的元素
Task input = this.workQueue.poll();
if (input == null) break;
//真正的去做业务处理
Object output = handle(input);
this.resultMap.put(Integer.toString(input.getId()),output);
}
}
private Object handle(Task input) {
Object output = null;
try {
//对数据源进行处理
Thread.sleep(500);
output = input.getPrice();
} catch (Exception e) {
e.printStackTrace();
}
return output;
}
}
总结
Master-Worker 模式是一种将串行任务并行化的方案,被分解的子任务在系统中可以被并行处理,同时,如果有需要,Master进程不需要等待所有子任务都完成计算,就可以根据已有的部分结果集计算最终结果集。