Java并发编程六 Master-Worker模式
Master-Worker是常用的并行计算模式。它的核心思想是系统由两类进程协作工作:Master进程和Worker进程。Master负责接收和分配任务,Worker负责处理子任务。当各个Worker子进程处理完成后,会将结果返回给Master,由Master作归纳总结。其好处就是能将一个大任务分解成若干个小任务,并行执行,从而提高系统的吞吐量。
Master-Worker 模式的结构相对比较简单,Master 进程为主要进程,它维护了一个Worker 进程队列、子任务队列和子结果集、Worker 进程队列中的 Worker 进程,不停地从任务队列中提取要处理的子任务,并将子任务的处理结果写入结果集。
/**
* Master进程为主要进程,它维护一个Worker进程队列、任务队列和子结果集。
* Created by lyyz on 18-5-15.
*/
public class Master {
// 一个放任务的队列
private ConcurrentLinkedQueue<Task> taskQueue = new ConcurrentLinkedQueue<Task>();
// 一个放worker的容器
private HashMap<String,Thread> workers = new HashMap<String,Thread>();
// 一个放每个任务处理的结果的结果集
private ConcurrentHashMap<String,Object> resultMap = new ConcurrentHashMap<String,Object>();
/**
* 构造函数
*
*
* @param worker
* @param workderCount
*/
public Master(Worker worker,int workderCount){
//step1 通过传入的worker和workerCount 创建workerCount个线程存入到workers容器里。
for(int i=1;i<=workderCount; i++){
workers.put("worker"+i,new Thread(worker,"worker"+i));
}
//step2 并且将master里的taskQueue,resultMap存入到worker的实例内
worker.setTaskQueue(taskQueue);
worker.setResultMap(resultMap);
}
/**
* 提供一个添加任务的方法,可想master里的任务队列中添加task任务
* @param task
*/
public void addTask(Task task){
taskQueue.add(task);
}
/**
* 提供一个执行master中workers容器中所有worker的方法
*/
public void exec(){
for(Map.Entry<String,Thread> me:workers.entrySet()){
me.getValue().start();
}
}
/**
* 提供一个判断workers容器中所有worker是否都执行完毕
* @return 返回是否所有worker都执行完毕
*/
public boolean isFinish(){
for(Map.Entry<String,Thread> me:workers.entrySet()){
if(me.getValue().isAlive()){
return false;
}
}
return true;
}
/**
* 归纳总结: 遍历结果集中的所有结果,并算出最终总数
* @return 结果集总和
*/
public int getResultCount(){
int result=0;
for(Map.Entry<String,Object> me :resultMap.entrySet()){
result+=(int)me.getValue();
}
return result;
}
}
/**
* Worker 具体工作的执行者 实现Runable接口 主要处理Masker的Task队列中的任务
* Created by lyyz on 18-5-15.
*/
public abstract class Worker implements Runnable {
// 指向 master中的taskQueue
private ConcurrentLinkedQueue<Task> taskQueue;
//指向 master中的resultMap
private ConcurrentHashMap<String,Object> resultMap;
/**
* 将master中的任务队列地址赋值到worker中的taskQueue上(都是master中的taskQueue)
* @param taskQueue
*/
public void setTaskQueue(ConcurrentLinkedQueue<Task> taskQueue){
this.taskQueue = taskQueue;
};
/**
* 将master中的结果集地址赋值到worker中的resultMap上(都是master中的resultMap)
* @param resultMap
*/
public void setResultMap(ConcurrentHashMap<String,Object> resultMap){
this.resultMap = resultMap;
};
/**
* 从taskQueue中取任务 并且将处理返回的结果存入到resultMap中
*/
@Override
public void run() {
while(true){
Task task = taskQueue.poll();
if(task ==null) break;
//真正处理的方法,放到子类中实现
int result = handle(task);
resultMap.put(task.getId(),result);
}
}
/**
* 真正处理的方法,放到子类中实现
* @param task
* @return
*/
public abstract int handle(Task task);
}
/**
* 继承Worker并且实现 handle方法
*
* Created by lyyz on 18-5-15.
*/
public class PriceWorker extends Worker {
/**
* 处理任务的具体方法
* @param task
* @return
*/
@Override
public int handle(Task task){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return task.getNum();
}
}
/**
* 具体的任务实体
* Created by lyyz on 18-5-15.
*/
public class Task {
private String id;
private String name;
private int num;
public Task(String id, String name, int num) {
this.id = id;
this.name = name;
this.num = num;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
/**
* 并发编程 Master-Worker模式
* Master-Worker是常用的并行计算模式。它的核心思想是系统由两类进程协作工作:Master进程和Worker进程。
* Master负责接收和分配任务,Worker负责处理子任务。当各个Worker子进程处理完成后,会将结果返回给Master,由Master作归纳总结。
* 其好处就是能将一个大任务分解成若干个小任务,并行执行,从而提高系统的吞吐量。
*
* Created by lyyz on 18-5-15.
*/
public class Main {
public static void main(String[] args) throws IOException {
//创建 Master实例
Master master = new Master(new PriceWorker(),10);
//实际开发中多少个线程最好写成Runtime.getRuntime().availableProcessors()
//Master master = new Master(new PriceWorker(),Runtime.getRuntime().availableProcessors());
//向master任务队列添加具体任务
Random random = new Random();
for(int i=1;i<=100;i++){
master.addTask(new Task("task"+i,"task"+i,random.nextInt(1000)));
}
//执行master的所有worker
master.exec();
long startTime = System.currentTimeMillis();
while(true){
//判断master中所有worker是否都执行完毕
if(master.isFinish()){
System.out.println("总和为:"+master.getResultCount()+", 总耗时为"+(System.currentTimeMillis()-startTime));
break;
}
}
}
}