JAVA多线程之Master worker并行设计模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a78270528/article/details/79759505

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


分析过程:

1、既然Worker是具体的执行任务,那么Worker一定要实现Runnable接口。

2、Matser作为接受和分配任务,得先有个容器来装载用户发出的请求,在不考虑阻塞的情况下我们选择ConcurrentLinkedQueue作为装载容器。

3、Worker对象需要能从Master接收任务,它也得有Master ConcurrentLinkedQueue容器的引用。

4、Master还得有个容器需要能够装载所有的Worker,可以使用HashMap<String,Thread>。

5、Worker处理完后需要将数据返回给Master,那么Master需要有个容器能够装载所有worker并发处理任务的结果集。此容器需要能够支持高并发,所以最好采用ConcurrentHashMap<String,Object>。

6、同理由于Worker处理完成后将数据填充进Master的ConcurrentHashMap,那么它也得有一份ConcurrentHashMap的引用 。


下面看一个例子:

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:设置不同的线程数耗时不同  
Master-Worker模式是一种将串行任务并行化的方案,被分解的子任务在系统中可以被并行处理,同时,如果有需要,Master进程不需要等待所有子任务都完成计算,就可以根据已有的部分结果集计算最终结果集。

猜你喜欢

转载自blog.csdn.net/a78270528/article/details/79759505
今日推荐