Future模式
并发的精髓应该是不等待,但是有些请求可能处理时间会比较长,必须等待。此时就做一个折中,就是服务端立马把请求返回,不让客户端等待结果,返回的是一个假结果,可能客户端这个时候也不着急,得到结果后就去做别的事了,服务端会接着去处理请求,处理完毕后,会通知客户端(回调)。这个时候客户端才会拿到真正想要的结果。
Master-Worker模式
一种典型的分治思想,Master-Worker模式是常用的并行模式之一,它的核心思想是,系统有两个进程协作工作:Master进程,负责接收和分配任务;Worker进程,负责处理子任务。当Worker进程将子任务处理完成后,结果返回给Master进程,由Master进程做归纳汇总,最后得到最终的结果。
master代码
public class Master {
//任务队列,work线程从这个队列中领取任务
private Queue<Task> taskQueue = new ConcurrentLinkedQueue<Task>();
//任务结果Map,worker线程执行完任务后,将执行结果放入这里
private Map<String, Object> taskResultMap = new ConcurrentHashMap<String, Object>();
//worker线程Map,方便Master对所有Worker的管理
private Map<String,Thread> workMap = new HashMap<String, Thread>();
//用来判断是否所有的线程都结束
private CountDownLatch countDownLatch ;
public Map<String, Object> getTaskResultMap() {
return taskResultMap;
}
public Master(Worker worker ,int workCount){
countDownLatch = new CountDownLatch(workCount);
for(int i=0;i<workCount;i++){
worker.setCountDownLatch(countDownLatch);
worker.setTaskQueue(taskQueue);
worker.setTaskResultMap(taskResultMap);
workMap.put("worker"+i,new Thread(worker,"worker"+i));
}
}
/**
* 提交任务
* @param task
*/
public void submit(Task task){
taskQueue.offer(task);
}
/**
* 执行任务
*/
public void execute(){
for(String workerId : workMap.keySet()){
workMap.get(workerId).start();
}
}
/**
* 等待所有的线程都结束
*/
public void complete(){
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
worker代码
public class Worker implements Runnable {
private Queue<Task> taskQueue = new ConcurrentLinkedQueue<Task>();
private Map<String, Object> taskResultMap = new ConcurrentHashMap<String, Object>();
private CountDownLatch countDownLatch;
public void setCountDownLatch(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
public void setTaskQueue(Queue<Task> taskQueue) {
this.taskQueue = taskQueue;
}
public void setTaskResultMap(Map<String, Object> taskResultMap) {
this.taskResultMap = taskResultMap;
}
public void run() {
while (true) {
Task task = taskQueue.poll();
if (task == null)
break;
taskResultMap.put(task.getTaskId() + "", task.handle());
}
countDownLatch.countDown();
}
}
task代码
/**
* Created by peter on 2017/4/6.
* 此为抽象类,具体的处理逻辑在子类中,也就是子类去实现handle方法
*/
public abstract class Task {
private int taskId;
private String taskName;
public int getTaskId() {
return taskId;
}
public Task(int taskId,String taskName){
this.taskId = taskId;
this.taskName = taskName;
}
//处理逻辑
public abstract Object handle();
}
下面举个例子,来计算1+2+3+4+…..的平方和
public class Main {
public static void main(String[] args) {
Worker worker = new Worker();
Master master = new Master(worker, 3);
for (int i = 0; i < 5; i++) {
master.submit(new CalcTask(i,"task"+i,i));
}
master.execute();
//等待所有线程都执行完毕
//也可以不等线程执行完毕,就开始计算,但是在每一轮计算结束后,都要移除taskResultMap中的key,以免重复计算
master.complete();
int result = 0;
for(String taskId : master.getTaskResultMap().keySet() ){
Object obj = master.getTaskResultMap().get(taskId);
result += (Integer)obj;
}
System.out.println("result: " + result);
}
}
/**
* 计算数的平方
*/
class CalcTask extends Task {
private int value;
public CalcTask(int taskId, String taskName, int value) {
super(taskId, taskName);
this.value = value;
}
@Override
public Object handle() {
return value * value;
}
}