Java多线程编程中Master-Worker模式的详解

Java多线程编程中,常用的多线程设计模式包括:Future模式、Master-Worker模式、Guarded Suspeionsion模式、不变模式和生产者-消费者模式等。这篇文章主要讲述Master-Worker模式,关于其他多线程设计模式的地址如下:
关于其他多线程设计模式的地址如下:
关于Future模式的详解:  Java多线程编程中Future模式的详解
关于Guarded Suspeionsion模式的详解:  Java多线程编程中Guarded Suspeionsion模式的详解
关于不变模式的详解:  Java多线程编程中不变模式的详解
关于生产者-消费者模式的详解: 生产者-消费者模式Java详解

1 Master-Worker模式核心思想

Master-Worker模式是常用的并行模式之一,它的核心思想是:系统由两类进程协同工作,即Master进程和Worker进程,Master负责接收和分配任务,Wroker负责处理子任务。当各个Worker进程将子任务处理完成后,将结果返回给Master进程,由Master进程进行汇总,从而得到最终的结果,其具体处理过程如下图所示。

Master进程为主要进程,它维护一个Worker进程队列、子任务队列和子结果集。Worker进程队列中的Worker进程不停从任务队列中提取要处理的子任务,并将结果写入结果集。


2 Master-Worker模式的代码实现

Worker类的Java实现

[java]  view plain  copy
  1. import java.util.Map;  
  2. import java.util.Queue;  
  3.   
  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.   
  13.     public void setResultMap(Map<String, Object> resultMap) {  
  14.         this.resultMap = resultMap;  
  15.     }  
  16.       
  17.     //子任务处理的逻辑,在这里不作具体实现,由子类实现  
  18.     public Object handle(Object input) {  
  19.         return input;  
  20.     }  
  21.       
  22.     @Override  
  23.     public void run() {  
  24.         while(true) {  
  25.             //获取子任务  
  26.             Object input = workQueue.poll();  
  27.             if(input == nullbreak;  
  28.             //处理子任务  
  29.             Object re = handle(input);  
  30.             //将处理结果写入结果集  
  31.             resultMap.put(Integer.toString(input.hashCode()), re);  
  32.         }  
  33.     }  
  34. }  
Master类的Java实现

[java]  view plain  copy
  1. import java.util.HashMap;  
  2. import java.util.Map;  
  3. import java.util.Queue;  
  4. import java.util.concurrent.ConcurrentHashMap;  
  5. import java.util.concurrent.ConcurrentLinkedQueue;  
  6.   
  7. public class Master {  
  8.     //任务队列  
  9.     protected Queue<Object> workQueue =   
  10.             new ConcurrentLinkedQueue<Object>();  
  11.     //Worker进程队列  
  12.     protected Map<String, Thread> threadMap =   
  13.             new HashMap<String, Thread>();  
  14.     //子任务处理结果集  
  15.     protected Map<String, Object> resultMap =  
  16.             new ConcurrentHashMap<String, Object>();  
  17.       
  18.     public Master(Worker worker, int countWorker) {  
  19.         worker.setWorkQueue(workQueue);  
  20.         worker.setResultMap(resultMap);  
  21.         for(int i=0; i<countWorker; i++) {  
  22.             threadMap.put(Integer.toString(i),   
  23.                     new Thread(worker, Integer.toString(i)));  
  24.         }  
  25.     }  
  26.       
  27.     //是否所有的子任务都介绍了  
  28.     public boolean isComplete() {  
  29.         for(Map.Entry<String, Thread> entry : threadMap.entrySet()) {  
  30.             if(entry.getValue().getState() != Thread.State.TERMINATED)  
  31.                 //存在为完成的线程  
  32.                 return false;  
  33.         }  
  34.         return true;  
  35.     }  
  36.       
  37.     //提交一个子任务  
  38.     public void submit(Object job) {  
  39.         workQueue.add(job);  
  40.     }  
  41.       
  42.     //返回子任务结果集  
  43.     public Map<String, Object> getResultMap() {  
  44.         return resultMap;  
  45.     }  
  46.       
  47.     //执行所有Worker进程,进行处理  
  48.     public void execute() {  
  49.         for(Map.Entry<String, Thread> entry : threadMap.entrySet()) {  
  50.             entry.getValue().start();  
  51.         }  
  52.     }  
  53. }  

3 Master-Worker模式的应用实例

利用Master-Worker模式实现计算立方和的应用。计算1^3+2^3+3^3+…+100^3。

这个计算任务被划分成100个子任务,每个任务仅仅用于计算单独的立方和。

Worker的子类

[java]  view plain  copy
  1. public class PlusWorker extends Worker { //求立方和  
  2.     @Override  
  3.     public Object handle(Object input) {  
  4.         int i = (Integer)input;  
  5.         return i * i * i;  
  6.     }  
  7. }  
运行

运行的调用函数如下。在主函数中首先通过Master类创建4个Worker工作进程和Worker工作实例PlusWorker。在提交了100个子任务后,边开始子任务的计算。这些子任务中由这4个进程共同完成。Master不用等待所有Worker计算完成才开始汇总,而是子任务在计算的过程中,Master就开始汇总了。

[java]  view plain  copy
  1. import java.util.Map;  
  2. import java.util.Set;  
  3.   
  4. public class Application {  
  5.     public static void main(String[] args) {  
  6.         //固定使用4个Workde  
  7.         Master master = new Master(new PlusWorker(), 4);  
  8.         for(int i=1; i<=100; i++) //提交100个子任务  
  9.             master.submit(i);  
  10.         master.execute(); //开始计算  
  11.           
  12.         Map<String, Object> resultMap = master.getResultMap();  
  13.           
  14.         int re = 0;  //最终计算结果保存在此  
  15.         //不需要等待所有Worker都执行完即可  
  16.         while(true) {  
  17.             Set<String> keys = resultMap.keySet();  //开始计算最终结果  
  18.             String key = null;  
  19.             for(String k : keys) {  
  20.                 key = k;  
  21.                 break;  
  22.             }  
  23.             Integer i = null;  
  24.             if(key != null)  
  25.                 i = (Integer)resultMap.get(key);  
  26.             if(i != null)  
  27.                 re += i; //最终结果  
  28.             if(key != null)  
  29.                 resultMap.remove(key); //移除已被计算过的项目  
  30.             if(master.isComplete() && resultMap.size()==0)  
  31.                 break;  
  32.         }  
  33.         System.out.println(re);  
  34.     }  
  35. }  
运行结果如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值