常见的并发设计模式

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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值