并发之Master-Worker设计模式

1.定义

Master-Worker模式是常用的并行设计模式。它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程。Master进程负责接收和分配任务,Worker进程负责处理子任务。当各个Worker进程将子任务处理完后,将结果返回给Master进程,由Master进行归纳和汇总,从而得到系统结果。

 

2.实现

2.1定义worker基类

package com.ldzn.concurrency.designpattern.masterworker;

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

/**
 * @ClassName : BaseWorker
 * @Description:
 * @Author: liulianglin
 * @Date: 2019/12/12 17:45
 * @Version : 1.0
 */
public class BaseWorker<T> implements Runnable{

    /**
     1.定义一个承载任务的集合
     */
    private ConcurrentLinkedQueue<MTask> taskQueue = new ConcurrentLinkedQueue<>();

    /**
     * 2. 定义一个承载所有worker执行结果的容器
     * ConcurrentHashMap
     */
    private ConcurrentHashMap<Integer, T> resultMap = new ConcurrentHashMap<>();

    public void setTaskQueue(ConcurrentLinkedQueue<MTask> taskQueue){
        this.taskQueue = taskQueue;
    }

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

    @Override
    public void run() {
        //循环处理任务
        while(true){
            MTask task = this.taskQueue.poll();
            if (null == task){
                System.out.println("取出任务为空");
                break;
            }
            System.out.println("从任务队列中取出一个任务,task="+task.getTaskName());

            //任务处理
            System.out.println("开始处理任务"+task.getTaskName());
            T result = null;
            try {
                result = handleTask(task);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.resultMap.put(task.getTaskId(), result);
        }

    }


    /**
     * 处理任务,由子类具体负责实现
     * @param task
     * @return
     */
    public T handleTask(MTask task) throws InterruptedException {
        return null;
    }
}

2.2定义一个worker实现类

package com.ldzn.concurrency.designpattern.masterworker;

/**
 * @ClassName : MWorker1
 * @Description:
 * @Author: liulianglin
 * @Date: 2019/12/12 18:02
 * @Version : 1.0
 */
public class MWorker1 extends BaseWorker<MResult> {

    @Override
    public MResult handleTask(MTask task) throws InterruptedException {
        System.out.println("进入worker1,开始处理taskId="+task.getTaskId()+ ", tasskName="+task.getTaskName());
        if (null == task){
            System.out.println("输入参数--任务为空");
            return null;
        }
        Thread.sleep(1000);
        MResult result = new MResult();
        result.setTaskId(task.getTaskId());
        result.setResult("woker1-----成功");
        System.out.println(task.getTaskName()+"执行完毕, 返回结果");
        return result;
    }

}

2.3定义一个Master

package com.ldzn.concurrency.designpattern.masterworker;

import com.sun.tools.javac.api.MultiTaskListener;

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

/**
 * @ClassName : MyMaster
 * @Description:
 * @Author: liulianglin
 * @Date: 2019/12/12 17:45
 * @Version : 1.0
 */
public class MyMaster<T> {
    /**
    1.定义一个承载任务的集合
     */
    private ConcurrentLinkedQueue<MTask> taskQueue = new ConcurrentLinkedQueue<>();

    /**
     * 2.定义一个承载worker的集合
     */
    private HashMap<String, Thread> workersMap = new HashMap<>();

    /**
     * 3. 定义一个承载所有worker执行结果的容器
     * ConcurrentHashMap
     *
     * key:taskId
     * value: 任务结果
     */
    private ConcurrentHashMap<Integer, T> resultMap = new ConcurrentHashMap<>();

    public MyMaster(BaseWorker worker, int workerCount){
        worker.setTaskQueue(this.taskQueue);
        worker.setResultMap(this.resultMap);

        for (int i=0; i<workerCount; i++){
            workersMap.put("子工作线程"+i, new Thread(worker));
        }
    }

    /**
     * 提交任务
     */
    public void submitTask(MTask mtask){
        taskQueue.add(mtask);
    }

    /**
     * 任务执行
     */
    public void executeTask(){
        //遍历所有workers,顺序启动所有worker线程
        for (Map.Entry<String, Thread> worker : workersMap.entrySet()){
            worker.getValue().start();
        }
    }

    /**
     * 判断所有的worker是否都执行完毕
     */
    public boolean isAllCompleted(){
        for (Map.Entry<String, Thread> worker : workersMap.entrySet()){
            if (worker.getValue().getState() != Thread.State.TERMINATED){
                return false;
            }
        }
        return true;
    }

    /**
     * 计算最终结果
     */
    public String getResult(){
        String result = null;
        for (Map.Entry<Integer, T> worker : resultMap.entrySet()){
            result += worker.getValue().toString();
            result += "\n";
        }
        return result;
    }


}

2.4定义一个任务类

package com.ldzn.concurrency.designpattern.masterworker;

/**
 * @ClassName : MTask
 * @Description:
 * @Author: liulianglin
 * @Date: 2019/12/12 17:46
 * @Version : 1.0
 */
public class MTask {
    private int taskId;
    private String taskName;

    public int getTaskId() {
        return taskId;
    }

    public void setTaskId(int taskId) {
        this.taskId = taskId;
    }

    public String getTaskName() {
        return taskName;
    }

    public void setTaskName(String taskName) {
        this.taskName = taskName;
    }

    @Override
    public String toString() {
        return "MTask{" +
                "taskId=" + taskId +
                ", taskName='" + taskName + '\'' +
                '}';
    }
}

2.5定义一个结果类

package com.ldzn.concurrency.designpattern.masterworker;

/**
 * @ClassName : MResult
 * @Description:
 * @Author: liulianglin
 * @Date: 2019/12/12 18:04
 * @Version : 1.0
 */
public class MResult {
    private int taskId;
    private String result;

    public int getTaskId() {
        return taskId;
    }

    public void setTaskId(int taskId) {
        this.taskId = taskId;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    @Override
    public String toString() {
        return "MResult{" +
                "taskId=" + taskId +
                ", result='" + result + '\'' +
                '}';
    }
}

2.6最后编写一个测试类

package com.ldzn.concurrency.designpattern.masterworker;

/**
 * @ClassName : MasterWokerTest
 * @Description: MasterWoker模式
 * @Author: liulianglin
 * @Date: 2019/12/12 10:56
 * @Version : 1.0
 */
public class MasterWokerTest {
    public static void main(String[] args) {
        MyMaster master = new MyMaster(new MWorker1(), 4);

        //构造4个任务
        for (int i = 0; i <= 4; i++){
            MTask task = new MTask();
            task.setTaskId(i);
            task.setTaskName("任务"+i);
            master.submitTask(task);
        }

        //执行
        master.executeTask();
        //记录时间
        long startTime = System.currentTimeMillis();
        while (true) {
            if (master.isAllCompleted()) {
                //记录时间
                long endTime = System.currentTimeMillis();
                System.out.println("\n最终执行结果-----" + master.getResult());
                System.out.println("执行耗时=" + (endTime - startTime));
                break;
            }
        }
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值