Master-Worker模式是常用的并行计算模式。它的核心思想是系统由两类进程协作工作:Master进程和Worker进程。Master负责接收和分配任务,Worker负责处理子任务。当各个Worker子进程处理完成后,会将结果返回给Master,由Master做归纳和总结。其好处是能将一个大任务分解成若干个小任务,并行执行,从而提高系统的吞吐量。
主要模块分为:
Master:中控调度作用,起到分配任务,汇总结果集。包含ConcurrentLinkedQueue容器承装所有的任务,HashMap<String,Thread>容器承装所有的worker对象,ConcurrentHashMap<String,Object>并发容器装载每个worker并发处理任务的结果集。
worker:实现Runnable接口或继承Thread实现多线程。每个worker对象需要有master的ConcurrentLinkedQueue的引用用于获取任务,每个worker对象需要有ConcurrentHashMap<String,Object>的引用用于承装返回结果
Main:调用Master进行测试
Task:封装任务
示例代码:
Master类:
public class Master {
//1.承装任务的容器
private ConcurrentLinkedQueue<Task> workQueue=new ConcurrentLinkedQueue<>();
//2.使用HashMap承装所有的worker对象
private HashMap<String, Thread> workers=new HashMap<>();
//3.使用一个容器承装每一个worker并行执行任务的结果集
private ConcurrentHashMap<String, Object> resultMap=new ConcurrentHashMap<>();
//4.构造方法(执行任务的worker对象,和创建worker的线程数)
public Master(Worker worker,int workerCount) {
//每一个worker对象都需要有Master的引用workerQueue用于任务的领取,resultMap用于任务的提交
worker.setWorkerQueue(this.workQueue);
worker.setResultMap(this.resultMap);
for (int i = 0; i < workerCount; i++) {
//key代表每个worker的名称,value表示每个worker
workers.put("子节点"+i, new Thread(worker));
}
}
//5.提交方法
public void submit(Task task) {
this.workQueue.add(task);
}
//6.需要一个执行方法(启动应用程序 让所有worker工作)
public void execute() {
for (Map.Entry<String, Thread> mt : workers.entrySet()) {
mt.getValue().start();
}
}
//7.判断线程是否执行完毕
public boolean isComplete() {
for (Map.Entry<String, Thread> mt : workers.entrySet()) {
if(mt.getValue().getState()!=Thread.State.TERMINATED) {
return false;
}
}
return true;
}
//8.返回结果集数据
public int getResult() {
int ret=0;
for (Map.Entry<String, Object> mt : resultMap.entrySet()) {
ret+=(Integer)mt.getValue();
}
return ret;
}
}
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=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 {
//表示处理Task任务的耗时,可能是数据的加工,也可能是操作数据库。。。。
Thread.sleep(500);
output=input.getPrice();
} catch (InterruptedException e) {
e.printStackTrace();
}
return output;
}}
Task类:
public class Task {
private int id;
private String name;
private int price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Task [id=" + id + ", name=" + name + ", price=" + price + "]";
}
}
Main类:
public class Main {
public static void main(String[] args) {
Worker worker=new Worker();
Master master=new Master(worker, 20);
Random r=new Random();
for (int i = 1; i <= 100; i++) {
Task task=new Task();
task.setId(i);
task.setName("任务"+i);
task.setPrice(r.nextInt(1000));
master.submit(task);
}
master.execute();
long start=System.currentTimeMillis();
while(true) {
if(master.isComplete()) {
long end=System.currentTimeMillis()-start;
int ret=master.getResult();
System.out.println("最终结果:"+ret+"执行耗时:"+end);
break;
}
}
}
}
运行结果:
最终结果:50622执行耗时:2501