并行-Master-Worker模式

     master-worker模式,我们生活中有很多这样的例子,比如一个小组会有一个组长,组长负责给每个人分配任务,也监控每个人的工作情况。

Master-Worker模式


      是常用的并行模式,它的核心思想是,系统由两个重要角色组成,一个为Master,用于任务的分配和最终结果的合成;一个为Worker,用于实际处理一个任务。

              


       Master-Worker模式的好处,它能够将一个大人物分解成若干个小任务,并行执行(体现分治的思想),从而可以提高系统的吞吐量。对于系统用户的请求,任务一旦提交,Master会分配任务并立即返回,并不会等待系统全部处理完成后再返回,它具体的处理时异步的。


      master-worker模式是使用多线程进行数据处理的结构,多个worker协作处理用户请求,mater负责维护worker,并负责整合最终结果集。


Master-Worker代码:


Master实现

package com.tgb.masterworker;


import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Created by zhangsisi on 2017/7/29.
 */
public class Master {
    /**
     * 任务列表
     */
    private Queue<Object> jobQueue = new ConcurrentLinkedQueue<Object>();

    /**
     * worker组
     */
    private Map<String,Thread> workers = new HashMap<>();

    /**
     * 结果集
     */
    private Queue<Object> results = new ConcurrentLinkedQueue<Object>();

    /**
     * 原始任务数
     */
    private AtomicLong oriJobNum = new AtomicLong(0);

    public Master(int workerNum, Class<? extends Worker> workerClass)
            throws IllegalAccessException, InstantiationException {
        for(int i=0;i<workerNum;i++){
            Worker worker = workerClass.newInstance();
            worker.setJobQueue(jobQueue);
            worker.setResults(results);
            worker.setId(i);
            workers.put(Integer.toString(i),
                    new Thread(worker,Integer.toString(i)));
        }
    }

    /**
     * 任务是否已经完成
     * @return
     */
    public boolean isComplete(){
        for(Map.Entry<String,Thread> worker:workers.entrySet()){
            if(Thread.State.TERMINATED!= worker.getValue().getState()){
                return false;
            }
        }
        return true;
    }

    /**
     * 由client端提交一个子任务
     * @param job
     */
    public void submit(Object job){
        oriJobNum.incrementAndGet();//允许动态增加任务
        jobQueue.add(job);
    }

    /**
     * 返回子任务结果集
     */
    public Queue<Object> getResults(){
        return results;
    }

    /**
     * 将运行结果放到结果集
     * @param result
     */
    public void putResult(Object result){
        results.add(result);
    }

    /**
     * 启动worker,进行任务处理
     */
    public void execute(){
        for(Map.Entry<String,Thread> entry:workers.entrySet()){
            entry.getValue().start();
        }
    }

    /**
     * 获取完成任务占比
     * @return
     */
    public float getFinishRatio(){
        return 100.0f - 100.0f *((float)jobQueue.size()/oriJobNum.get());
    }

}

Worker实现

package com.tgb.masterworker;

import java.util.Queue;

/**
 * Created by zhangsisi on 2017/7/29.
 */
public abstract class Worker implements Runnable{
    private int id;

    //任务队列,用于获得子任务
    protected Queue<Object> jobs;

    //子任务处理结果集
    protected Queue<Object> results;

    //子任务的处理逻辑,在子类中实现具体逻辑
    public abstract Object handle(Object input);

    @Override
    public void run() {
        System.out.println(String.format("Worker:[%d] start working...",this.id));

        while (true){
            //贪婪式获取任务
            Object input = jobs.poll();

            if(null == input) break;

            //将处理结果写入结果集
            putResult(handle(input));
        }
        System.out.println(String.format("Worker:[%d] finish the jobs...",this.id));
    }

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

    public void setJobQueue(Queue<Object> jobQueue) {
        this.jobs = jobQueue;
    }

    public void setResults(Queue<Object> results) {
        this.results = results;
    }

    private void putResult(Object result){
        results.add(result);
    }
}

PlusWorker实现

package com.tgb.masterworker;

/**
 * Created by zhangsisi on 2017/7/29.
 */
public class PlusWorker extends Worker {
    @Override
    public Object handle(Object input) {
        long i =(Long)input;
        return i*i*i;
    }
}


Client客户端调用

package com.tgb.masterworker;

import java.util.Queue;

/**
 * Created by zhangsisi on 2017/7/29.
 */
public class Client {
    private static int jobNum = 100;

    public static void main(String[] args) throws InterruptedException {
        testMasterWorker();
        System.out.println("-----------------");
    }

    static void testMasterWorker() throws InterruptedException {
        Master master = null;

        try {
            //固定4个Worker
            master = new Master(4,PlusWorker.class);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

        //提交100个子任务
        for(long i = 1;i<=jobNum;i++){
            master.submit(i);
        }
        //开始计算
        master.execute();

        long re =0;
        while (true){
            //等待计算结束
            if(master.isComplete()){
                Queue<Object> results = master.getResults();
                for(Object result:results){
                    re = re + (long)result;
                }
                System.out.println(master.getFinishRatio()+"%");
                break;
            }
            else{
                System.out.println(master.getFinishRatio()+"%");
                Thread.sleep(1);
            }
        }
        System.out.println(re);
    }


}

结果

       
       

总结:

       master-worker模式是一种将串行任务并行化的方法,被分解的子任务在系统中可被并行处理。采用的是分治的思想,将大任务分解为小的任务,启用多个线程进行并行处理,提高系统的吞吐量。





评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值