并发编程:Master-Worker模式

        Master-Worker模式是常用的并行计算模式,其核心思想是系统由两类进程协作工作:Master和Worker进程。Master负责接收和分配任务,Worker负责处理子任务。当Worker完成子任务后会将结果返回给Master,Master则对Worker们的返回结果做归纳和总结,其好处是将一个大任务分解成若干个小任务,并发执行从而提高系统的吞吐量。从某种角度来讲,其思想跟“分治”还是有点相似的。

        下面给出一段小例子来进行模拟Master-worker模式:

Master:

        master应当有三个容器,分别用于存放Task任务、Worker以及Worker执行Task后的返回结果集。master主要有四个方法,分别是submit(Task task)(用于提交任务,即将Task放到Task容器里边,这里我们使用了ConcurrentLinkedQueue队列来充当Task容器)、execute()(任务装载完毕,master启动worker们去完成task任务)、isComplete()(master用于判断worker是否已经完成其具体的任务)、getResult()(获取已经完成任务的worker的结果)。master有其对应的构造方法Master(Worker worker,int workerCount)用于初始化一个master。

public class Master {
	//容器一:存放来自main的任务,这里涉及到并发,所以使用并发类容器
	private ConcurrentLinkedQueue<Task> workQueue = new ConcurrentLinkedQueue<Task>();
	//容器二:存放Worker,由于有Master进行分配,使每一个Worker不存在并发,所以使用普通容器
	private HashMap<String,Thread> workerMap = new HashMap<String,Thread>();
	//容器三:存放Worker们的任务返回结果集,由于这里涉及到并发,所以使用并发类容器
	private ConcurrentHashMap<String,Object> resultMap = new ConcurrentHashMap<String,Object>();
	
	//构造一个Master
	@SuppressWarnings("unused")
	private Master() {}
	public Master(Worker worker,int workerCount) {
		worker.setWorkQueue(this.workQueue);
		worker.setResultMap(this.resultMap);
		for(int index = 0;index < workerCount;index++) {
			this.workerMap.put(Integer.toString(index), new Thread(worker));
		}
	}
	//提交任务
	public void submit(Task task) {
		this.workQueue.add(task);
	}
	//启动Worker们去执行任务
	public void execute() {
		for(Map.Entry<String, Thread> me : workerMap.entrySet()) {
			me.getValue().start();
		}
	}
	//判断一个Worker是否运行结束
	public boolean isComplete() {
		for(Map.Entry<String, Thread> me : workerMap.entrySet()) {
			if(me.getValue().getState() != Thread.State.TERMINATED) {
				return false;
			}
		}
		return true;
	}
	//计算结果
	public int getResult() {
		int priceResult = -1;
		for(Map.Entry<String, Object> me : resultMap.entrySet()) {
			priceResult += (Integer)me.getValue();
		}
		return priceResult;
	}

}

Worker:

        Worker们都是独立的一个线程,所以应当实现Runnable接口。Worker应当有一个任务队列workQueue用于装载这一个worker所需要执行的任务,有一个结果集resultMap用于装载这个worker执行每一个任务的结果。worker应当有一个任务处理方法 handle(Task input) 用于处理master分配给他的任务。

public class Worker implements Runnable {
	private ConcurrentLinkedQueue<Task> workQueue;
	private ConcurrentHashMap<String,Object> resultMap;
	
	public void setWorkQueue(ConcurrentLinkedQueue<Task> workQueue) {
		this.workQueue = workQueue;
	}
	public void setResultMap(ConcurrentHashMap<String,Object> resultMap) {
		this.resultMap = resultMap;
	}
	
	@Override
	public void run() {
		while(true) {
			Task input = this.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 {
			//假设处理一个任务耗时5秒
			Thread.sleep(5*1000);
			output = input.getPrice();
		}catch(Exception e) {
			System.err.println(e.getMessage());
		}
		return output;
	}
}

Task:

        task表示任务,一个请求可能存在N个任务,master将这些任务分配给不同的worker进行处理。这里我们假设任务为计算,给出Task类:

public class Task {
	private int id;
	private int price;
	...
    get/set方法
    ...
	@Override
	public String toString() {
		return "Task [id=" + id + ", price=" + price + "]";
	}
}

下面进行测试,给出测试类如下:

	public static void main(String[] args) {
		Master master = new Master(new Worker(),1000);
		Random r = new Random(System.currentTimeMillis());
		for(int index = 1;index < 1001;index++) {
			Task task = new Task();
			task.setId(index);
			task.setPrice(r.nextInt(1000));
			master.submit(task);
		}
		System.err.println("下面开始执行任务");
		master.execute();
		long start = System.currentTimeMillis();
		while(true) {
			if(master.isComplete()) {
				long spend = System.currentTimeMillis() - start;
				int priceResult = master.getResult();
				System.err.println("最终结果:"+priceResult+",执行时间:"+spend/1000+"秒");
				break;
			}
		}
	}

执行N次:

	//20个worker:10-5;20-5;30-10;40-10;50-15;60-15;100-25;1000-250(task数量-执行时间)
	//200个worker:1000-25(task数量-执行时间)
	//1000个worker:1000-5(task数量-执行时间)
	//2000个worker:1000-4(task数量-执行时间)
            

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值