这个类主要介绍程序开发过程中的Master—Worker模式
该模式是常用的并行模式之一。
核心思想是:系统由两类进程协作:Master进程和Worker进程。
Master进程负责接收和分配任务,Worker负责处理子任务。当各个worker进程将子任务处理完成后,将结果返回
给Master,由Master进程做归纳和汇总, 从而得到系统的复杂结果。
优点是:它能够将一个大任务分解成若干个小任务,可以并行执行,提高系统的吞吐率。
现在附Master-Worker代码如下(主要包括四个类Master,Worker,PlusWorker,Main),其中Master和Worker类给出了Master-Worker模式的框架,而PlusWorke则是继承Worker类,重写handle方法,实现子任务具体在实际过程中做的工作,Main类则是包含启动Master-Worker模式的方法。
public class Master{ //主进程Master类
/**任务队列<br>*/
protected Queue<Object> workQueue = new ConcurrentLinkedQueue<Object>();
/**进程队列<br>*/
protected Map<String,Thread> threadMap = new HashMap<String,Thread>();
/**子任务处理结果集<br>*/
protected Map<String,Object> resultMap = new ConcurrentHashMap<String,Object>();
/**@author zk
* @see 判断是否所有的子任务都结束了
* @return 如果所有的任务都完成可则返回true,否则返回false
*/
public boolean isComplete(){
// for (Thread thread : threadMap.values()) {
// if(thread.getState() != Thread.State.TERMINATED){
// return false;
// }
// }
//
for(Map.Entry<String, Thread> entry : threadMap.entrySet()){
if(entry.getValue().getState()!=Thread.State.TERMINATED){//如果有一个任务的状态不是终止,则说明没有完成所有的任务
return false;
}
}
return true;
}
/**@author zk
* 主进程Master的构造函数
* @param Worker 子任务
* @param countWorker 子任务的个数
*/
public Master(Worker worker,int countWorker){
worker.setResultMap(resultMap);
worker.setWorkQueue(workQueue);
for(int i=0;i<countWorker;i++){
threadMap.put(Integer.toString(i), new Thread(worker,Integer.toString(i)));
}
}
/**@author zk
* 提交一个任务
* @param job
*/
public void submit(Object job){
workQueue.add(job);//相当于是往workQueue工作队列中加上一个任务
}
/**@author zk
* 返回子任务结果集
* @return
*/
public Map<String, Object> getResultMap() {
return resultMap;
}
/**@author zk
* 开始运行所有的Worker进程,进行处理
* 也就是说,调用这个execute()方法相当于主进程把任务都分给了子进程去处理
*/
public void execute(){
for(Map.Entry<String, Thread> entry : threadMap.entrySet()){
entry.getValue().start();
}
}
}
public class Worker implements Runnable {
protected Queue<Object> workQueue;
protected Map<String,Object> resultMap ;
public void setWorkQueue(Queue<Object> workQueue) {
this.workQueue = workQueue;
}
public void setResultMap(Map<String, Object> resultMap) {
this.resultMap = resultMap;
}
/**@author zk
* 子任务处理逻辑,在子类中实现具体逻辑
* @param input
* @return
*/
public Object handle(Object input){
return input;
}
@Override
public void run() {
while(true){
Object input = workQueue.poll();
if(input == null){ //说明所有的任务都已经被完成了
break;
}
Object re = handle(input);//处理获取到的任务
/*将处理结果放到resultMap中*/
resultMap.put(Integer.toString(input.hashCode()), re);
}
}
}
public class PlusWorker extends Worker{
public Object handle(Object input){
Integer i = (Integer) input;
return i*i*i;
}
}
public class Main {
public static void main(String args[]) throws InterruptedException{
Long start = System.currentTimeMillis();
Master m = new Master(new PlusWorker(),5);
for(int i=1;i<=100;i++){//提交100个子任务
m.submit(i);
}
m.execute();//开始计算
int re = 0;
Map<String,Object> resultMap = m.getResultMap();
while(resultMap.size()>0 || !m.isComplete()){ //不必等所有的子任务运行完就可以开始合并resultMap的结果
Set<String> keys = resultMap.keySet();
String key = null;
for(String k:keys){
key = k;
break;
}
Integer i = null;
if(key != null){//取出key对应的结果
i = (Integer) resultMap.get(key);
}
if(i != null){
re += i;
}
if(key!=null){
resultMap.remove(key);//移除已经被计算过得项
}
}
System.out.println("re = "+re);
Long end = System.currentTimeMillis();
System.out.println("总花费时间 = "+(end-start)+"ms");
}
}