Master-Worker模式是常用的并行模式之一,它的核心思想是,系统有两个进程协作工作:Master进程,负责接收和分配任务;Worker进程,负责处理子任务。当Worker进程将子任务处理完成后,结果返回给Master进程,由Master进程做归纳汇总,最后得到最终的结果。
一、什么是Master-Worker模式:
该模式的结构图:

Worker:用于实际处理一个任务;

Master:任务的分配和最终结果的合成;

Main:启动程序,调度开启Master。

注意点:

Master必须存在一个队列来存储客户端发送过来的任务,必须有一个队列,我们选择无阻塞无界队列

Worker实际处理任务的操作者,所以应该是线程,应该实现runnable接口

master应该有一个容器装所有的worker对象,不涉及到高并发,使用hashmap ,value就是worker对象

worker需要拥有master进程中的无阻塞无界队列的引用,用来获得任务进行处理

master是对worker处理的结果做归纳总结,所以需要有一个队列要保存worker处理的结果,要实现并发安全的ConcurrentHashMap

worker需要拥有ConcurrentHashMap的引用,把处理的结果存储在ConcurrentHashMap中,需要线程安全的

Master-Worker模式是一种将串行任务并行化的方案。
更重要的是提供了一种变化的思想。

我们来看下面程序的代码:

  1. package com.bjsxt.height.design015;
  2.  
  3. public class Task {
  4.  
  5. private int id;
  6. private int price ;
  7. public int getId() {
  8. return id;
  9. }
  10. public void setId(int id) {
  11. this.id = id;
  12. }
  13. public int getPrice() {
  14. return price;
  15. }
  16. public void setPrice(int price) {
  17. this.price = price;
  18. }
  19.  
  20. }
  1. package com.bjsxt.height.design015;
  2.  
  3. import java.util.concurrent.ConcurrentHashMap;
  4. import java.util.concurrent.ConcurrentLinkedQueue;
  5.  
  6. public class Worker implements Runnable {
  7.  
  8. private ConcurrentLinkedQueue<Task> workQueue;
  9. private ConcurrentHashMap<String, Object> resultMap;
  10.  
  11. public void setWorkQueue(ConcurrentLinkedQueue<Task> workQueue) {
  12. this.workQueue = workQueue;
  13. }
  14.  
  15. public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
  16. this.resultMap = resultMap;
  17. }
  18.  
  19. @Override
  20. public void run() {
  21. while(true){
  22. Task input = this.workQueue.poll();
  23. if(input == null) break;
  24. Object output = handle(input);
  25. this.resultMap.put(Integer.toString(input.getId()), output);
  26. }
  27. }
  28.  
  29. private Object handle(Task input) {
  30. Object output = null;
  31. try {
  32. //处理任务的耗时。。 比如说进行操作数据库。。。
  33. Thread.sleep(500);
  34. output = input.getPrice();
  35. } catch (InterruptedException e) {
  36. e.printStackTrace();
  37. }
  38. return output;
  39. }
  40.  
  41. }
  1. package com.bjsxt.height.design015;
  2.  
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import java.util.concurrent.ConcurrentHashMap;
  6. import java.util.concurrent.ConcurrentLinkedQueue;
  7.  
  8. public class Master {
  9.  
  10. //1 有一个盛放任务的容器
  11. private ConcurrentLinkedQueue<Task> workQueue = new ConcurrentLinkedQueue<Task>();
  12.  
  13. //2 需要有一个盛放worker的集合
  14. private HashMap<String, Thread> workers = new HashMap<String, Thread>();
  15.  
  16. //3 需要有一个盛放每一个worker执行任务的结果集合
  17. private ConcurrentHashMap<String, Object> resultMap = new ConcurrentHashMap<String, Object>();
  18.  
  19. //4 构造方法
  20. public Master(Worker worker , int workerCount){
  21. worker.setWorkQueue(this.workQueue);
  22. worker.setResultMap(this.resultMap);
  23. /**
  24. * 初始化woker对象的个数,管理worker对象,开启100个worker对象,装到hashmap中
  25. * */
  26. for(int i = 0; i < workerCount; i ++){
  27. this.workers.put(Integer.toString(i), new Thread(worker));
  28. }
  29.  
  30. }
  31.  
  32. //5 需要一个提交任务的方法
  33. public void submit(Task task){
  34. /**
  35. * 添加到任务队列中
  36. * */
  37. this.workQueue.add(task);
  38. }
  39.  
  40. //6 需要有一个执行的方法,启动所有的worker方法去执行任务
  41. public void execute(){
  42. for(Map.Entry<String, Thread> me : workers.entrySet()){
  43. me.getValue().start();
  44. }
  45. }
  46.  
  47. //7 判断是否运行结束的方法
  48. public boolean isComplete() {
  49. for(Map.Entry<String, Thread> me : workers.entrySet()){
  50. if(me.getValue().getState() != Thread.State.TERMINATED){
  51. return false;
  52. }
  53. }
  54. return true;
  55. }
  56.  
  57. //8 计算结果方法
  58. public int getResult() {
  59. int priceResult = 0;
  60. for(Map.Entry<String, Object> me : resultMap.entrySet()){
  61. priceResult += (Integer)me.getValue();
  62. }
  63. return priceResult;
  64. }
  65.  
  66. }
  1. package com.bjsxt.height.design015;
  2.  
  3. import java.util.Random;
  4.  
  5. public class Main {
  6.  
  7. public static void main(String[] args) {
  8.  
  9. Master master = new Master(new Worker(), 20);
  10.  
  11. Random r = new Random();
  12. for(int i = 1; i <= 100; i++){
  13. Task t = new Task();
  14. t.setId(i);
  15. t.setPrice(r.nextInt(1000));
  16. master.submit(t);
  17. }
  18. master.execute();
  19. long start = System.currentTimeMillis();
  20.  
  21. while(true){
  22. if(master.isComplete()){
  23. long end = System.currentTimeMillis() - start;
  24. int priceResult = master.getResult();
  25. System.out.println("最终结果:" + priceResult + ", 执行时间:" + end);
  26. break;
  27. }
  28. }
  29.  
  30. }
  31. }

程序运行的结果是:

最终结果:54386, 执行时间:2500

将每个worker计算得到的price结果进行相加

相当的经典,这种设计模式就是将串行化的思想转换成并行化进行处理

多线程集成设计模式--MasterWorker模式讲解(一)的更多相关文章

  1. 多线程集成设计模式--future模式

    多线程开发可以更好的发挥多核cpu性能,常用的多线程设计模式有:Future.Master-Worker.Guard Susperionsion 一.什么是Future模型: 该模型是将异步请求和代理 ...

  2. 14.多线程设计模式 - Master-Worker模式

    多线程设计模式 - Master-Worker模式 并发设计模式属于设计优化的一部分,它对于一些常用的多线程结构的总结和抽象.与串行相比并行程序结构通常较为复杂,因此合理的使用并行模式在多线程并发中更 ...

  3. 并行程序设计模式--Master-Worker模式

    简介 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进程负责接收和分配任务,Worker进程负责处理子任务 ...

  4. 转 Master-Worker模式 并行程序设计模式--Master-Worker模式

    简介 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进程负责接收和分配任务,Worker进程负责处理子任务 ...

  5. 多线程设计模式 : Master-Worker模式

    Master-Worker是常用的并行计算模式.它的核心思想是系统由两类进程协作工作:Master进程和Worker进程.Master负责接收和分配任务,Worker负责处理子任务.当各个Worker ...

  6. 多线程的设计模式--Future模式,Master-Worker模式,生产者-消费者模式

    代码示例: public interface Data { String getRequest(); } public class FutureData implements Data{ privat ...

  7. Java多线程编程中Future模式的详解

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  8. Java多线程编程中Future模式的详解<转>

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  9. Master-Worker模式

    并行程序设计模式--Master-Worker模式 简介 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进 ...

随机推荐

  1. 慕零的黑夜-头条-第一期(必问)[导读:]1.CSDN必问赏金流向何方 2.CSDN必问偷偷做的手脚 3.CSDN必问靠谱吗 4.关于钱于回答的平衡问题:一美元拍卖骗局 作者:qq3461896724

    本期是关于CSDN 必问 (biwen.csdn.net)的内容,欢迎评论 文末,文中插入有 小姐姐 img(附py代码,1.49G) + coding资料 哟~~~ 你看到这篇很可能是在提问.推荐加 ...

  2. jQuery 获取页面宽高

    无滚动条的情况下(页面宽高比可视区域小):$(document)和$(window)的width.height方法获取的值都是一样的,都是可视区域的宽高即$(document).width()==$( ...

  3. PMP 冲!|项目整合管理

    0x00概述 项目管理包括识别.定义.组合.统一与协调各项目管理过程组的过程及项目管理活动.包括在各个项目冲突的目标与方案之间进行权衡和选择. 整合管理包括进行如下选择: 资源分配: 平衡竞争性需求: ...

  4. 01 . Tomcat简介及部署

    Tomcat简介 Tomcat背景 tomcat就是常用的的中间件之一,tomcat本身是一个容器,专门用来运行java程序,java语言开发的网页.jsp就应该运行于tomcat中.而tomcat本 ...

  5. Rocket - tilelink - toBools

    https://mp.weixin.qq.com/s/UGMH8EoaVcFkkQW-l4HLWg   分析toBools在Intellij中显示为红色的问题.   ​​   1. 问题   在TLA ...

  6. 一招解决GitHub致命的下载速度(GitHub下载速度慢怎么办)

    通过码云来导入github,通过码云下载 第一步: 找一个你需要下载的GitHub项目 第二步: 复制链接 第三步: 打开码云,然后选择从GitHub导入 第四步: 复制刚才的连接,起个名字,点击导入 ...

  7. Java实现 LeetCode 416 分割等和子集

    416. 分割等和子集 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: ...

  8. java实现 洛谷 P1014 Cantor表

    题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 1/5 - 2/1 2/2 2/3 2/4 - ...

  9. Java实现第九届蓝桥杯书号验证

    书号验证 2004年起,国际ISBN中心出版了<13位国际标准书号指南>. 原有10位书号前加978作为商品分类标识:校验规则也改变. 校验位的加权算法与10位ISBN的算法不同,具体算法 ...

  10. SOA架构和微服务架构的区别与特点

    1.SOA架构和微服务架构的区别 首先SOA和微服务架构一个层面的东西,而对于ESB和微服务网关是一个层面的东西,一个谈到是架构风格和方法,一个谈的是实现工具或组件. 1.SOA(Service Or ...