Master worker并行设计模式

介绍

    在多线程程序设计中Master worker 模式是常用的并行模式之一,核心思想是由两类进程协助完成的,Master 进程负责接收和分配任务并处理保存结果集,Worker 负责处理任务, 并把结果返回给Master 进程. 这类设计模式最大的好处是 将一个大任务分配成若干个小任务并行执行。可见master-worker 模式适合与将大任务化成小任务并行执行的情况,各个小任务基本并行独立运行,最终提供效率。

示例

public class Master {
    private List<Thread> threads = new ArrayList<Thread>();
    private Queue taskQueue = new ConcurrentLinkedQueue();//线程安全Queue,频繁增加和删除

    //线程安全Map,如果不需要key做业务的话也可以使用ConcurrentLinkedQueue
    protected Map<Object, Object> resultMap = new ConcurrentHashMap<Object, Object>();

    private AtomicInteger taskCount;//所有任务数量
    protected AtomicInteger commitCount;//完成各项子任务后汇报以确定全部任务是否已完成

    public Master(Worker worker, int workerCount) {
        taskCount = new AtomicInteger();
        commitCount = new AtomicInteger();
        worker.setTaskQueue(taskQueue);
        worker.setResultMap(resultMap);
        worker.setCommitCount(commitCount);
        for (int i = 0; i < workerCount; i++) {
            threads.add(new Thread(worker));
        }
    }

    public void submit(Object obj) {
        taskQueue.add(obj);
        taskCount.incrementAndGet();
    }

    public void execute() {
        for (Thread t : threads) {
            t.start();
        }
    }

    public Map<Object, Object> getResultMap() {
        return resultMap;
    }

    public boolean isComplete() {
        return (commitCount.get() == taskCount.get()) && resultMap.isEmpty();
    }
}
public abstract class Worker implements Runnable {
    protected Queue taskQueue;
    protected Map<Object, Object> resultMap;
    protected AtomicInteger commitCount;

    public void setTaskQueue(Queue taskQueue) {
        this.taskQueue = taskQueue;
    }
    public void setResultMap(Map<Object, Object> resultMap) {
        this.resultMap = resultMap;
    }
    public void setCommitCount(AtomicInteger commitCount) {
        this.commitCount = commitCount;
    }
    @Override
    public void run() {
        for (Object input; (input = taskQueue.poll()) != null; ) {
            Object result = handle(input);
            resultMap.put(input, result);
            commitCount.incrementAndGet();
        }
    }
    protected abstract Object handle(Object input);
}
public class PlusWorker extends Worker {
    @Override
    protected Object handle(Object input) {
        Integer obj = (Integer) input;
        try {
            Thread.sleep(new Random().nextInt(100));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return obj * obj * obj;
    }
}
public class Main {
    public static void main(String[] args) {
        // 模拟计算立方和
        int count = 500;
        Master master = new Master(new PlusWorker(), 100);//相当于100个人每个人算一个立方和,最后Master算加法。
        for (int i = 1; i <= count; i++) {
            master.submit(i);
        }
        long start = System.currentTimeMillis();
        master.execute();//开始执行
        Map<Object, Object> resultMap = master.getResultMap();//对结果集进行操作
        long total = 0;//最终结果

        //只是为了作示例,出于简单考虑,没有使用阻塞、同步等控制
        while (!master.isComplete()) {
            for (Map.Entry<Object, Object> handleResult : resultMap.entrySet()) {
                total += (Integer) handleResult.getValue();
                resultMap.remove(handleResult.getKey());
            }
            try {Thread.sleep(10);} catch (Exception e) {}
        }
        System.out.println("耗时:" + (System.currentTimeMillis() - start));
        System.out.println("合计结果:" + total);
    }
}
测试结果:

耗时:326
合计结果:15687562500

ps:设置不同的线程数耗时不同


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值