Java并发编程六 Master-Worker模式

Java并发编程六 Master-Worker模式

Master-Worker是常用的并行计算模式。它的核心思想是系统由两类进程协作工作:Master进程和Worker进程。Master负责接收和分配任务,Worker负责处理子任务。当各个Worker子进程处理完成后,会将结果返回给Master,由Master作归纳总结。其好处就是能将一个大任务分解成若干个小任务,并行执行,从而提高系统的吞吐量
master-worker
Master-Worker 模式的结构相对比较简单,Master 进程为主要进程,它维护了一个Worker 进程队列、子任务队列和子结果集、Worker 进程队列中的 Worker 进程,不停地从任务队列中提取要处理的子任务,并将子任务的处理结果写入结果集。

/**
 * Master进程为主要进程,它维护一个Worker进程队列、任务队列和子结果集。
 * Created by lyyz on 18-5-15.
 */
public class Master {
    // 一个放任务的队列
    private ConcurrentLinkedQueue<Task> taskQueue = new ConcurrentLinkedQueue<Task>();
    // 一个放worker的容器
    private HashMap<String,Thread> workers = new HashMap<String,Thread>();
    // 一个放每个任务处理的结果的结果集
    private ConcurrentHashMap<String,Object> resultMap = new ConcurrentHashMap<String,Object>();

    /**
     * 构造函数
     *
     *
     * @param worker
     * @param workderCount
     */
    public Master(Worker worker,int workderCount){
        //step1 通过传入的worker和workerCount 创建workerCount个线程存入到workers容器里。
        for(int i=1;i<=workderCount; i++){
            workers.put("worker"+i,new Thread(worker,"worker"+i));
        }
        //step2 并且将master里的taskQueue,resultMap存入到worker的实例内
        worker.setTaskQueue(taskQueue);
        worker.setResultMap(resultMap);
    }

    /**
     * 提供一个添加任务的方法,可想master里的任务队列中添加task任务
     * @param task
     */
    public void addTask(Task task){
        taskQueue.add(task);
    }

    /**
     * 提供一个执行master中workers容器中所有worker的方法
     */
    public void exec(){
        for(Map.Entry<String,Thread> me:workers.entrySet()){
            me.getValue().start();
        }
    }

    /**
     * 提供一个判断workers容器中所有worker是否都执行完毕
     * @return 返回是否所有worker都执行完毕
     */
    public boolean isFinish(){

        for(Map.Entry<String,Thread> me:workers.entrySet()){
            if(me.getValue().isAlive()){
                return false;
            }
        }
        return true;
    }

    /**
     * 归纳总结: 遍历结果集中的所有结果,并算出最终总数
     * @return 结果集总和
     */
    public int getResultCount(){
        int result=0;
        for(Map.Entry<String,Object> me :resultMap.entrySet()){
            result+=(int)me.getValue();
        }

        return result;
    }
}
/**
 * Worker 具体工作的执行者 实现Runable接口 主要处理Masker的Task队列中的任务
 * Created by lyyz on 18-5-15.
 */
public abstract class Worker implements Runnable {
    // 指向 master中的taskQueue
    private ConcurrentLinkedQueue<Task> taskQueue;
    //指向 master中的resultMap
    private ConcurrentHashMap<String,Object> resultMap;

    /**
     * 将master中的任务队列地址赋值到worker中的taskQueue上(都是master中的taskQueue)
     * @param taskQueue
     */
    public void setTaskQueue(ConcurrentLinkedQueue<Task> taskQueue){
        this.taskQueue = taskQueue;
    };
    /**
     * 将master中的结果集地址赋值到worker中的resultMap上(都是master中的resultMap)
     * @param resultMap
     */
    public void setResultMap(ConcurrentHashMap<String,Object> resultMap){
        this.resultMap = resultMap;
    };

    /**
     * 从taskQueue中取任务 并且将处理返回的结果存入到resultMap中
     */
    @Override
    public void run() {
        while(true){
            Task task = taskQueue.poll();
            if(task ==null) break;
            //真正处理的方法,放到子类中实现
            int result = handle(task);
            resultMap.put(task.getId(),result);
        }

    }

    /**
     * 真正处理的方法,放到子类中实现
     * @param task
     * @return
     */
    public abstract int handle(Task task);
}

/**
 * 继承Worker并且实现 handle方法
 *
 * Created by lyyz on 18-5-15.
 */
public class PriceWorker extends Worker {
    /**
     * 处理任务的具体方法
     * @param task
     * @return
     */
    @Override
    public int handle(Task task){
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return task.getNum();

    }
}
/**
 * 具体的任务实体
 * Created by lyyz on 18-5-15.
 */
public class Task {
    private String id;
    private String name;
    private int num;

    public Task(String id, String name, int num) {
        this.id = id;
        this.name = name;
        this.num = num;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}
/**
 * 并发编程 Master-Worker模式
 * Master-Worker是常用的并行计算模式。它的核心思想是系统由两类进程协作工作:Master进程和Worker进程。
 * Master负责接收和分配任务,Worker负责处理子任务。当各个Worker子进程处理完成后,会将结果返回给Master,由Master作归纳总结。
 * 其好处就是能将一个大任务分解成若干个小任务,并行执行,从而提高系统的吞吐量。
 *
 * Created by lyyz on 18-5-15.
 */
public class Main {
    public static void main(String[] args) throws IOException {
        //创建 Master实例
        Master master = new Master(new PriceWorker(),10);
        //实际开发中多少个线程最好写成Runtime.getRuntime().availableProcessors()
        //Master master = new Master(new PriceWorker(),Runtime.getRuntime().availableProcessors());

        //向master任务队列添加具体任务
        Random random = new Random();
        for(int i=1;i<=100;i++){
            master.addTask(new Task("task"+i,"task"+i,random.nextInt(1000)));
        }
        //执行master的所有worker
        master.exec();

        long startTime = System.currentTimeMillis();
        while(true){
            //判断master中所有worker是否都执行完毕
            if(master.isFinish()){
                System.out.println("总和为:"+master.getResultCount()+", 总耗时为"+(System.currentTimeMillis()-startTime));
                break;
            }
        }

    }
}

猜你喜欢

转载自blog.csdn.net/oyueyang1/article/details/80322458