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

一、什么是Master-Worker模式:

该模式的结构图:

结构图:

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

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

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

二、代码实现:

下面的是一个简易的Master-Worker框架实现。

(1)Master部分:

  1. package MasterWorker;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import java.util.Queue;
  5. import java.util.concurrent.ConcurrentHashMap;
  6. import java.util.concurrent.ConcurrentLinkedQueue;
  7. public class Master {
  8. //任务队列
  9. protected Queue<Object> workQueue= new ConcurrentLinkedQueue<Object>();
  10. //Worker进程队列
  11. protected Map<String ,Thread> threadMap= new HashMap<String ,Thread>();
  12. //子任务处理结果集
  13. protected Map<String ,Object> resultMap= new ConcurrentHashMap<String, Object>();
  14. //是否所有的子任务都结束了
  15. public boolean isComplete(){
  16. for(Map.Entry<String , Thread> entry:threadMap.entrySet()){
  17. if(entry.getValue().getState()!=Thread.State.TERMINATED){
  18. return false;
  19. }
  20. }
  21. return true ;
  22. }
  23. //Master的构造,需要一个Worker进程逻辑,和需要Worker进程数量
  24. public Master(Worker worker,int countWorker){
  25. worker.setWorkQueue(workQueue);
  26. worker.setResultMap(resultMap);
  27. for(int i=0;i<countWorker;i++){
  28. threadMap.put(Integer.toString(i),  new Thread(worker, Integer.toString(i)));
  29. }
  30. }
  31. //提交一个任务
  32. public void submit(Object job){
  33. workQueue.add(job);
  34. }
  35. //返回子任务结果集
  36. public Map<String ,Object> getResultMap(){
  37. return resultMap;
  38. }
  39. //开始运行所有的Worker进程,进行处理
  40. public  void execute(){
  41. for(Map.Entry<String , Thread> entry:threadMap.entrySet()){
  42. entry.getValue().start();
  43. }
  44. }
  45. }

(2)Worker进程实现:

  1. package MasterWorker;
  2. import java.util.Map;
  3. import java.util.Queue;
  4. public class Worker  implements Runnable{
  5. //任务队列,用于取得子任务
  6. protected Queue<Object> workQueue;
  7. //子任务处理结果集
  8. protected Map<String ,Object> resultMap;
  9. public void setWorkQueue(Queue<Object> workQueue){
  10. this.workQueue= workQueue;
  11. }
  12. public void setResultMap(Map<String ,Object> resultMap){
  13. this.resultMap=resultMap;
  14. }
  15. //子任务处理的逻辑,在子类中实现具体逻辑
  16. public Object handle(Object input){
  17. return input;
  18. }
  19. @Override
  20. public void run() {
  21. while(true){
  22. //获取子任务
  23. Object input= workQueue.poll();
  24. if(input==null){
  25. break;
  26. }
  27. //处理子任务
  28. Object re = handle(input);
  29. resultMap.put(Integer.toString(input.hashCode()), re);
  30. }
  31. }
  32. }

(3)运用这个小框架计算1——100的立方和,PlusWorker的实现:

  1. package MasterWorker;
  2. public class PlusWorker extends Worker {
  3. @Override
  4. public Object handle(Object input) {
  5. Integer i =(Integer)input;
  6. return i*i*i;
  7. }
  8. }

(4)进行计算的Main函数:

  1. package MasterWorker;
  2. import java.util.Map;
  3. import java.util.Set;
  4. public class Main {
  5. /**
  6. * @param args
  7. */
  8. public static void main(String[] args) {
  9. //固定使用5个Worker,并指定Worker
  10. Master m = new Master(new PlusWorker(), 5);
  11. //提交100个子任务
  12. for(int i=0;i<100;i++){
  13. m.submit(i);
  14. }
  15. //开始计算
  16. m.execute();
  17. int re= 0;
  18. //保存最终结算结果
  19. Map<String ,Object> resultMap =m.getResultMap();
  20. //不需要等待所有Worker都执行完成,即可开始计算最终结果
  21. while(resultMap.size()>0 || !m.isComplete()){
  22. Set<String> keys = resultMap.keySet();
  23. String key =null;
  24. for(String k:keys){
  25. key=k;
  26. break;
  27. }
  28. Integer i =null;
  29. if(key!=null){
  30. i=(Integer)resultMap.get(key);
  31. }
  32. if(i!=null){
  33. //最终结果
  34. re+=i;
  35. }
  36. if(key!=null){
  37. //移除已经被计算过的项
  38. resultMap.remove(key);
  39. }
  40. }
  41. }
  42. }

三、总结:

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

转:http://blog.csdn.net/lmdcszh/article/details/39698189

多线程设计模式(三):Master-Worker模式的更多相关文章

  1. Java多线程设计模式(4)线程池模式

    前序: Thread-Per-Message Pattern,是一种对于每个命令或请求,都分配一个线程,由这个线程执行工作.它将“委托消息的一端”和“执行消息的一端”用两个不同的线程来实现.该线程模式 ...

  2. java设计模式三种工厂模式简单介绍

    一.简单工厂模式 概述:简单工厂模式的创建意图就是,把对类的创建初始化全都交给一个工厂来执行,而用户不需要去关心创建的过程是什么样的,只用告诉工厂我想要什么就行了.而这种方法的缺点也很明显,违背了设计 ...

  3. java设计模式---三种工厂模式

    工厂模式提供创建对象的接口. 工厂模式分为三类:简单工厂模式(Simple Factory), 工厂方法模式(Factory Method)和抽象工厂模式(Abstract Factory).GOF在 ...

  4. java设计模式---三种工厂模式之间的区别

    简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式.其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性. 本文是本人对这三种模式学习后的一个小结以及对他 ...

  5. Java经典23结构模型的设计模式(三)------附加代理模式、适配器型号、Facade模式的差异

    本文介绍了7样的结构模型中的其余2种:轻量级.代理模式. 一.享元模式FlyWeight 享元模式比較简单且重要,在非常多场合都被用到.仅仅只是封装起来了用户看不到.其概念:运用共享内存技术最大限度的 ...

  6. java23种设计模式——三、工厂模式

    源码在我的github和gitee中获取 工厂模式 工厂模式介绍 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式.著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在J ...

  7. java设计模式(三)--抽象工厂模式

    转载:http://zz563143188.iteye.com/blog/1847029 前面的工厂方法模式虽然清晰,但还是感觉有些繁琐,通常使用的还是抽象工厂模式. 工厂方法模式有一个问题就是,类的 ...

  8. JAVA中的设计模式三(策略模式)

    问题: 如何让算法和对象分开来,使得算法可以独立于使用它的客户而变化?   方案: 把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就 ...

  9. java常用设计模式三:原型模式

    在说原型模式之前先说一下浅拷贝和深拷贝的概念 一.浅拷贝和深拷贝 1.浅拷贝 在java中,对象创建后需要有一个引用变量来指向该对象实际的地址空间,也就是说引用变量与对象实体是两个不同的数据体.在Ob ...

  10. 设计模式—三种工厂模式(JAVA)

    一:简单工厂: 有一个实际工厂,这个工厂只能造一类的产品,这一类产品就是一个产品接口,会有多个具体产品实现这个接口,例 如,一个手机厂,生产苹果手机,三星手机: 缺点:在工厂类中集中了所有实例的创建逻 ...

随机推荐

  1. 使用springmvc时报错HTTP Status 400 -

    这个错误大多是因为,jsp的form表单提交的字段类型和后台接收字段类型不匹配造成的(例如,form中为String,后台接收为Integer). 我这里就是jsp表单中的日期数据没有写明类型,然后用 ...

  2. activity启动模式之singleTask

    activity启动模式之singleTask 一.简介 如果另外一个应用调用了C2,C2在栈底,如果这个程序里面再嗲用C1,C3,C2,那么这个C2就是调用onNewIntant的,C1和C3都被销 ...

  3. ImageView显示网络上的图片

    ImageView显示网络上的图片 一.简介 二.方法 1)ImageView显示网络上的图片方法 第一步:从网络上下载图片 byte[] byteArr = downImage();//这个是自己写 ...

  4. ToggleButton开关状态按钮控件

    ToggleButton开关状态按钮控件 一.简介 1. 2.ToggleButton类结构 父类是CompoundButton,引包的时候注意下 二.ToggleButton开关状态按钮控件使用方法 ...

  5. Python IOError: [Errno 22] invalid mode ('r') 解决方法

    环境 Anaconda3 Python 3.6, Window 64bit 书籍 O'Reilly出版的Wes McKinney编的<Python for Data Analysis> r ...

  6. 使用科大讯飞时碰上的问题(unity调用Android)

    使用科大讯飞的时候公司已经有人配置好了Android项目,由于装机量的限制,所以基本上要更换里面的资源和更改app_id,然而在unity那边调用的时候总是出现各种各样的问题,特此记录下来 1.唤醒未 ...

  7. python中配置文件的使用

    一. 什么是配置文件?为什么要做配置文件? 将所有的代码和配置都变成模块化可配置化,这样就提高了代码的重用性,不再每次都去修改代码内部,这个就是我们逐步要做的事情,可配置化 二. python中的Co ...

  8. Oracle DBLink连接数过多的问题(Ora-02020)

    前不久开发人员编译存储时报ORA -02020 错,如下是解决方案步骤.   报错全信息: Error:OR A -04052在查: 找远程对象 NIP.PB_PERADDRESSLIST@DB_NI ...

  9. 下载并安装Prism5.0库 Download and Setup Prism Library 5.0 for WPF(英汉对照版)

    Learn what’s included in Prism 5.0 including the documentation, WPF code samples, and libraries. Add ...

  10. Agilent RF fundamentals (8) Oscillator Decisions

          ----------------------