java中的并行模式之Master-Worker模式

这个类主要介绍程序开发过程中的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");
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值