线程安全——Master-Worker并发组件设计模拟

Master-Worker并发组件设计模拟

Master-Worker模式是常用的并行计算模式。它的核心思想是系统由两类进程协作工作:
Master进程和Worker进程。
Master负责接收和分配任务,Worker负责处理子任务。当各个Worker子进程处理完成后,
会将结果返回给Master,由Master做归纳和总结。
其好处是能将一个大任务分解成若干个小任务,并行执行,从而提高系统的吞吐量。

 

 代码结构;

 代码实现:

执行的任务

package com.bfxy.thread.core.design.masterworker;

public class Task {

	private int id;
	private int count;
	
	public Task() {
	}

	public Task(int id, int count) {
		this.id = id;
		this.count = count;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
	
}

master:

//1 承装任务的一个容器:支持高并发无界队列
private ConcurrentLinkedQueue<Task> taskQueue = new ConcurrentLinkedQueue<>();
//2 承装worker执行器:只需要执行数据不需要收集所以用HashMap
private HashMap<String, Thread> workers = new HashMap<>();
//3 接受worker处理成功的结果集合:高并发中存放结果集合所以使用ConcurrentHashMap
private ConcurrentHashMap<String, Object> resultMap = new ConcurrentHashMap<>();
package com.bfxy.thread.core.design.masterworker;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public class Master {

	//1 承装任务的一个容器:
	private ConcurrentLinkedQueue<Task> taskQueue = new ConcurrentLinkedQueue<>();
	
	//2 承装worker执行器
	private HashMap<String, Thread> workers = new HashMap<>();
	
	//3 接受worker处理成功的结果集合
	private ConcurrentHashMap<String, Object> resultMap = new ConcurrentHashMap<>();
	
	//4 构造方法里面,要对worker进行一个初始化操作
	public Master(Worker worker, int workCount) {
		//4.1 每一个worker 应该有master里 任务队列容器的引用
		worker.setTaskQueue(this.taskQueue);
		//4.2 每一个worker 应该有master里 结果集容器的引用
		worker.setResultMap(this.resultMap);
		//4.3 我们把所有的worker进行初始化 放入 workers容器中
		for(int i = 0; i < workCount; i ++){
			this.workers.put(Integer.toString(i), new Thread(worker));
		}
	}
	
	//5 需要一个提交任务的方法
	public void submit(Task task) {
		this.taskQueue.add(task);
	}
	
	//6 需要有一个真正让我们Master里的所有Worker进行工作的方法
	public void execute() {
		for(Map.Entry<String, Thread> me : this.workers.entrySet()) {
			me.getValue().start();
		}
	}
	
	//7 需要有一个统计的方法,用于合并结果集
	public int getResult() {
		int sum = 0;
		for(Map.Entry<String, Object> me : resultMap.entrySet()) {
			sum += (Integer)me.getValue();
		}
		return sum;
	}

	//8 判断是否所有的worker都完成工作了 如果完成返回true
	public boolean isComplete() {
		for(Map.Entry<String, Thread> me : this.workers.entrySet()) {
			if(me.getValue().getState() != Thread.State.TERMINATED){
				return false;
			}
		}
		return true;
	}
	
	
}

worker:属于线程执行类需要继承runnable接口

this.taskQueue.poll();//poll()方法,取到元素移除
package com.bfxy.thread.core.design.masterworker;

import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public class Worker implements Runnable {

	private ConcurrentLinkedQueue<Task> taskQueue;
	
	private ConcurrentHashMap<String, Object> resultMap;
	
	public void setTaskQueue(ConcurrentLinkedQueue<Task> taskQueue) {
		this.taskQueue = taskQueue;
	}

	public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
		this.resultMap = resultMap;
	}

	@Override
	public void run() {
		while(true) {
			Task task = this.taskQueue.poll();
			if(task == null) break;
			try {
				Object result = handle(task);
				this.resultMap.put(Integer.toString(task.getId()), result);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
 
	private  Random r = new Random();
	
	//实际做每一个工作!
	private Object handle(Task task) throws Exception {
		//每一个任务处理的时间是:
		//Thread.sleep(200 * r.nextInt(10));
		Thread.sleep(200);
		int ret = task.getCount();
		return ret;
	}
}

主函数测试:

package com.bfxy.thread.core.design.masterworker;

import java.util.Random;

public class Main {

	
	public static void main(String[] args) {
		
		System.err.println("线程数:" + Runtime.getRuntime().availableProcessors());
		Master master = new Master(new Worker(), Runtime.getRuntime().availableProcessors());
		
		Random r = new Random();
		
		for(int i = 0; i < 100; i ++) {
			Task t = new Task(i, r.nextInt(1000));
			master.submit(t);
		}
		
		master.execute();
		
		long start = System.currentTimeMillis();
		
		//CountDownLatch
		
		while(true) {
			if(master.isComplete()) {
				long end = System.currentTimeMillis();
				int result = master.getResult();
				System.err.println("最终执行结果: " + result + ", 总耗时: " + (end - start));
				break;
			}
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

择业

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值