Master Worker 属于并发类设计模式,简单理解就是一个主线程接收任务,然后创建多个子线程执行任务操作,操作完后由主线程汇总,在子线程执行操作的过程中,主线程可以继续添加任务。
并发计算立方和代码示例:
Master 负责接收任务,控制子线程执行,提供执行结果
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class Master {
/**
* 任务队列
*/
protected Queue<Object> workQueue = new LinkedBlockingQueue<Object>();
/**
* 线程 Map
*/
protected Map<String, Thread> threadMap = new HashMap<String, Thread>();
/**
* 每个任务的结果 Map
*/
protected Map<String, Object> resultMap = new HashMap<String, Object>();
/**
* @param worker 任务执行引擎
* @param workercnt 开启的任务执行引擎数量
*/
public Master(Worker worker, int workercnt) {
worker.setWorkQueue(workQueue);
worker.setResultMap(resultMap);
// 添加指定数量的处理线程
for (int i = 0; i < workercnt; i++) {
threadMap.put(Integer.toString(i), new Thread(worker, Integer.toString(i)));
}
}
/**
* 判断任务队列的任务是否计算完成
* @return true | false
*/
public boolean isComplete() {
for (Map.Entry<String, Thread> entry : threadMap.entrySet()) {
if (entry.getValue().getState() != Thread.State.TERMINATED) {
return false;
}
}
return true;
}
/**
* 暴露出添加任务的接口
* @param object
* @return
*/
public boolean submit(Object object) {
return workQueue.offer(object);
}
/**
* 获取结果集
* @return
*/
public Map<String, Object> getResultMap() {
return resultMap;
}
/**
* 启动所有的执行引擎
*/
public void execute() {
for (Map.Entry<String, Thread> entry : threadMap.entrySet()) {
entry.getValue().start();
}
}
}
Worker 子线程共享 Master 的任务队列和结果集,并将执行结果放入结果集
import java.util.Map;
import java.util.Queue;
public class Worker implements Runnable {
/**
* 工作队列,所有的执行引擎共享 Master 的工作队列
*/
protected Queue<Object> workQueue;
/**
* 结果集,所有的执行引擎共享 Master 的结果集
*/
protected Map<String, Object> resultMap;
public Queue<Object> getWorkQueue() {
return workQueue;
}
public void setWorkQueue(Queue<Object> workQueue) {
this.workQueue = workQueue;
}
public Map<String, Object> getResultMap() {
return resultMap;
}
public void setResultMap(Map<String, Object> resultMap) {
this.resultMap = resultMap;
}
public void run() {
// 不停的执行操作,知道任务队列没数据
while (true) {
Object input = workQueue.poll();
if (input == null) {
break;
}
// 真正的操作可以由子类去重写 handle
Object result = handle(input);
// 将操作结果放入共享结果集
resultMap.put(Integer.toString(input.hashCode()), result);
}
}
/**
* 可以丢给子类去重写
* @param object
* @return rewrite object
*/
public Object handle(Object object) {
return object;
}
}
这里 CubeWorker 一个重写的子线程,计算立方值
import java.util.Random;
public class CubeWorker extends Worker {
/**
* 重写后变成计算数字的立方
* @param object
* @return
*/
@Override
public Object handle(Object object) {
// 3s内随机睡眠,计算耗时假象
try {
Thread.sleep(new Random().nextInt(3000));
} catch (InterruptedException e) {
e.printStackTrace();
}
Integer value = (Integer) object;
return value * value * value;
}
}
测试类 SumCubesTest 先添加工作任务-触发子线程执行-求和结果
import java.util.Map;
public class SumCubesTest {
public static void main(String args[]) {
// 计时器
long timeBegin = System.currentTimeMillis();
// 这里可以通过修改执行引擎数量,看随后执行时间
Master master = new Master(new CubeWorker(), 100);
// 添加任务
for (int i = 1; i <= 100; i++) {
master.submit(i);
}
// 启动所有的执行引擎执行
master.execute();
int result = 0;
Map<String, Object> resultMap = master.getResultMap();
// 不停的从结果集拿数据出来做复合计算(结果集数据不是由同一线程产生的)
while (!resultMap.isEmpty() || !master.isComplete()) {
for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
result += (Integer) entry.getValue();
resultMap.remove(entry.getKey());
}
}
// 数据最终结果
System.out.println(result);
// 输出执行时间
System.out.println("cost: " + (System.currentTimeMillis() - timeBegin) + "ms");
}
}