Master - Worker 设计模式

我先简单得介绍一下master-worker设计模式。5个任务每个任务的执行时间是5秒在单线程的情况下需要跑55=25秒,在多线程的情况下 比如说开5个线程则是(5(5+开闭线程的时间))/5 约等于5秒。master-worker就是为了解决这一场景的,当然5个线程必须是逻辑无序的,这点应该容易理解。

Master主人在整个模式中它的作用只有接收和分配任务。

worker 工人则是具体得执行任务。最后将任务返回给master。

相当于将大的任务分成若干小份,并发执行 从而提高效率。

现在我们来设计一下这个系统。

Master

  1. Master必须要有一个容器来存放任务。这里我们选择ConcurrentLinkedQueue,因为worker肯定是并发的拿到里面的任务去执行。所以我们选择并发类容器来存储任务。
  2. master可以选用HashMap<String ,Thread>()来存储所有的worker对象。为什么不用concurrentHashMap?因为根本没有涉及到高并发的读写,不过怎么说呢用了也行。
  3. master需要有容器来存储worker执行完任务后的结果。我就用ConcurrentHashMap<String, Object>(); 来存储。原因同1,因为每个线程执行完任务后肯定是并发地往集合里放数据。
  4. 因为worek是具体得处理数据。所有必须实现runnable接口,原因不解释。
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public class Master {

    //任务队列  
    protected Queue<Object> workQueue= new ConcurrentLinkedQueue<Object>();
    //Worker进程队列  
    protected Map<String ,Thread> threadMap= new HashMap<String ,Thread>();
    //子任务处理结果集  
    protected Map<String ,Object> resultMap= new ConcurrentHashMap<String, Object>();
    //是否所有的子任务都结束了  
    public boolean isComplete(){
        for(Map.Entry<String , Thread> entry:threadMap.entrySet()){
            if(entry.getValue().getState()!=Thread.State.TERMINATED){
                return false;
            }

        }
        return true ;
    }

    //Master的构造,需要一个Worker进程逻辑,和需要Worker进程数量  
    public Master(Worker worker,int countWorker){

        worker.setWorkQueue(workQueue);
        worker.setResultMap(resultMap);
        for(int i=0;i<countWorker;i++){
            threadMap.put(Integer.toString(i),  new Thread(worker, Integer.toString(i)));
        }

    }

    //提交一个任务  
    public void submit(Object job){
        workQueue.add(job);
    }


    //返回子任务结果集  
    public Map<String ,Object> getResultMap(){
        return resultMap;
    }


    //开始运行所有的Worker进程,进行处理  
    public  void execute(){
        for(Map.Entry<String , Thread> entry:threadMap.entrySet()){
            entry.getValue().start();

        }
    }


}

Worker

  1. worker要对master的任务队列有引用,毕竟worker是要从master中取任务的
  2. worker 要对master的结果集合有引用,因为worker执行完结果后要存放结果集合
import java.util.Map;
import java.util.Queue;

public class Worker  implements Runnable{

    //任务队列,用于取得子任务  
    protected Queue<Object> workQueue;
    //子任务处理结果集  
    protected Map<String ,Object> resultMap;
    public void setWorkQueue(Queue<Object> workQueue){
        this.workQueue= workQueue;
    }

    public void setResultMap(Map<String ,Object> resultMap){
        this.resultMap=resultMap;
    }
    //子任务处理的逻辑,在子类中实现具体逻辑  
    public Object handle(Object input){
       //模拟耗时
        Thread.sleep(3000)
        return input;
    }


    @Override
    public void run() {

        while(true){
            //获取子任务  
            Object input= workQueue.poll();
            if(input==null){
                break;
            }
            //处理子任务  
            Object re = handle(input);
            resultMap.put(Integer.toString(input.hashCode()), re);
        }
    }

}

在worker中我把handle抽了出来。

有了这两个类的话主函数随便写一下。

开5线程5任务多少都行,或者自己把任务抽出来也行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值