多线程模式之Master-Worker

一. 介绍

需要使用Master-Worker的场景:主线程开了多个子进程(Worker进程)去执行任务时,主线程希望能收集到每个子进程的执行结果。
所以,Master-Worker模式基本上就是:
1.在Master进程中,定义好需要执行的任务集和需要收集的结果集
2.每一个子进程(Worker进程)从任务集中取一个任务执行,将执行结果写入结果集
3.Master根据结果集的内容做相应的处理
模式结构如下图所示:

二. 基本代码实现

Master 进程:

class Master{
    private Queue<Integer> workerQueue = new ConcurrentLinkedQueue<Integer>();
	
    private Map<String, Object> resultMap = new HashMap<String,Object>();
	
    private List<Thread> threadList = new ArrayList<Thread>();
	
    public Master(Worker worker){
        worker.setWorkerQueue(workerQueue);
	worker.setResultMap(resultMap);
	
	for(int i=0; i<5; i++){    //比如,开5个子进程
	    threadList.add(new Thread(worker));
	}
    }

    public Map<String, Object> getResultMap(){
	return resultMap;
    }
	
    public void execute(){
	for(Thread thread: threadList){
	    thread.start();
	}
    }
	
    //判断所有子进程是否结束了
    public Boolean isCompleted(){
	for(Thread thread: threadList){
	    if(thread.getState() != Thread.State.TERMINATED){
		return false;
	    }
	}
    	return true;
    }
}

Worker 进程

class Worker implements Runnable{
    private Queue<Integer> workerQueue;
	
    private Map<String, Object> resultMap;
	
    public void setResultMap(Map map){
	this.resultMap = map;
    }
    public Map<String, Object> getResultMap(){
	return resultMap;
    }
    public void setWorkerQueue(Queue workerQueue){
	this.workerQueue = workerQueue;
    }
	
    public void handle(Object task){
	// TODO
	/**
	 * 此处就是任务处理程序
	 * */
    }
	
    @Override
    public void run() {
    	// TODO
	Object task = workerQueue.poll();
	if(task != null){
	    handle(task);
	}	
    }
}

主函数:

Worker worker = new Worker();
Master master = new Master(worker);
master.execute();
while(!master.isCompleted){
    //TODO
    //此处可以对master.resultMap进行获取处理,不一定要等所有任务执行完毕
}

从Worker代码中可以看到,Master是将任务集和结果集通过Setter注入到Worker中,任务集用队列存储,是线程安全的。具体的处理就写在Worker的handle方法中

posted @ 2017-02-15 13:06  Bencakes  阅读(417)  评论(0编辑  收藏  举报