master-worker模式是一种并行计算模式,分为master进程和worker进程两个部分,master是担任总管角色,worker才是执行具体任务的地方。

  总体流程应该是这样的:

具体一点,代码实现流程应该是这样的:

client:

  1. import java.util.Random;
  2.  
  3. public class Main {
  4.  
  5. public static void main(String[] args) {
  6.  
  7. Master master = new Master(new Worker(), 20);//并发数20,也就是有20个Worker在工作
  8.  
  9. Random r = new Random();
  10. for(int i = 1; i <= 100; i++){//总共有100个任务
  11. Task t = new Task();
  12. t.setId(i);
  13. t.setPrice(r.nextInt(1000));
  14. master.submit(t);//提交任务,向WorkerQueue<Task> 中加入元素
  15. }
  16. master.execute();//启动所有的worker
  17. long start = System.currentTimeMillis();
  18.  
  19. while(true){
  20. if(master.isComplete()){//100个任务执行完成
  21. long end = System.currentTimeMillis() - start;
  22. int priceResult = master.getResult();//获取所有任务的执行结果
  23. System.out.println("最终结果:" + priceResult + ", 执行时间:" + end);
  24. break;
  25. }
  26. }
  27.  
  28. }
  29. }

Master:

  1. import java.util.HashMap;
  2. import java.util.Map;
  3. import java.util.concurrent.ConcurrentHashMap;
  4. import java.util.concurrent.ConcurrentLinkedQueue;
  5.  
  6. public class Master {
  7.  
  8. //1 有一个盛放任务的容器
  9. private ConcurrentLinkedQueue<Task> workQueue = new ConcurrentLinkedQueue<Task>();
  10.  
  11. //2 需要有一个盛放worker的集合
  12. private HashMap<String, Thread> workers = new HashMap<String, Thread>();
  13.  
  14. //3 需要有一个盛放每一个worker执行任务的结果集合
  15. private ConcurrentHashMap<String, Object> resultMap = new ConcurrentHashMap<String, Object>();
  16.  
  17. //4 构造方法
  18. public Master(Worker worker , int workerCount){
  19. worker.setWorkQueue(this.workQueue);
  20. worker.setResultMap(this.resultMap);
  21.  
  22. for(int i = 0; i < workerCount; i ++){
  23. this.workers.put(Integer.toString(i), new Thread(worker));
  24. }
  25.  
  26. }
  27.  
  28. //5 需要一个提交任务的方法
  29. public void submit(Task task){
  30. this.workQueue.add(task);
  31. }
  32.  
  33. //6 需要有一个执行的方法,启动所有的worker方法去执行任务
  34. public void execute(){
  35. for(Map.Entry<String, Thread> me : workers.entrySet()){
  36. me.getValue().start();
  37. }
  38. }
  39.  
  40. //7 判断是否运行结束的方法
  41. public boolean isComplete() {
  42. for(Map.Entry<String, Thread> me : workers.entrySet()){
  43. if(me.getValue().getState() != Thread.State.TERMINATED){
  44. return false;
  45. }
  46. }
  47. return true;
  48. }
  49.  
  50. //8 计算结果方法
  51. public int getResult() {
  52. int priceResult = 0;
  53. for(Map.Entry<String, Object> me : resultMap.entrySet()){
  54. priceResult += (Integer)me.getValue();
  55. }
  56. return priceResult;
  57. }

Worker:

  1. import java.util.concurrent.ConcurrentHashMap;
  2. import java.util.concurrent.ConcurrentLinkedQueue;
  3.  
  4. public class Worker implements Runnable {
  5.  
  6. private ConcurrentLinkedQueue<Task> workQueue;
  7. private ConcurrentHashMap<String, Object> resultMap;
  8.  
  9. public void setWorkQueue(ConcurrentLinkedQueue<Task> workQueue) {
  10. this.workQueue = workQueue;
  11. }
  12.  
  13. public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
  14. this.resultMap = resultMap;
  15. }
  16.  
  17. @Override
  18. public void run() {
  19. while(true){
  20. Task input = this.workQueue.poll();
  21. if(input == null) break;
  22. Object output = handle(input);
  23. this.resultMap.put(Integer.toString(input.getId()), output);
  24. }
  25. }
  26.  
  27. private Object handle(Task input) {
  28. Object output = null;
  29. try {
  30. //处理任务的耗时。。 比如说进行操作数据库。。。
  31. Thread.sleep(500);
  32. output = input.getPrice();
  33. } catch (InterruptedException e) {
  34. e.printStackTrace();
  35. }
  36. return output;
  37. }
  38.  
  39. }

Task:

  1. public class Task {
  2.  
  3. private int id;
  4. private int price ;
  5. public int getId() {
  6. return id;
  7. }
  8. public void setId(int id) {
  9. this.id = id;
  10. }
  11. public int getPrice() {
  12. return price;
  13. }
  14. public void setPrice(int price) {
  15. this.price = price;
  16. }
  17.  
  18. }

架构师养成记--10.master-worker模式的更多相关文章

  1. 架构师养成记--9.future模式讲解

    什么是future模式呢?解释这个概念之前我们先来了解一个场景吧,财务系统的结账功能,这个功能可能是每个月用一次,在这一个月中相关的数据量已经积累得非常大,这一个功能需要调用好几个存储过程来完成.假如 ...

  2. 架构师养成记--35.redis集群搭建

    前记:redis哨兵经验之谈.哨兵做主从切换可能要花费一两秒,这一两秒可能会丢失很多数据.解决方法之一是在java代码中做控制,try catch 到 链接断开的异常就sleep 一两秒钟再conti ...

  3. 架构师养成记--11.Executor概述

    常用方法 Executors.newFiexdPool(int nThreads);固定线程数量的线程池: Executors.newSingleThreadExecutor();单个线程的线程池: ...

  4. 架构师养成记--8.Queue

    一.ConcurrentLinkedQueue 是一个适合在高并发场景下,无锁,无界的,先进先出原则.不允许为null值,add().offer()加入元素,这两个方法没区别:pull().peek( ...

  5. 架构师养成记--15.Disruptor并发框架

    一.概述 disruptor对于处理并发任务很擅长,曾有人测过,一个线程里1s内可以处理六百万个订单,性能相当感人. 这个框架的结构大概是:数据生产端 --> 缓存 --> 消费端 缓存中 ...

  6. 架构师养成记--6.单例和多线程、ThreadLocal

    一.ThreadLocal 使用wait/notify方式实现的线程安全,性能将受到很大影响.解决方案是用空间换时间,不用锁也能实现线程安全. 来看一个小例子,在线程内的set.get就是thread ...

  7. 架构师养成记--4.volatile关键字

    volatile修饰的变量可在多个线程间可见. 如下代码,在子线程运行期间主线程修改属性值并不对子线程产生影响,原因是子线程有自己独立的内存空间,其中有主内存中的变量副本. public class ...

  8. 架构师养成记--3.synchronized细节问题

    一.synchronized有锁重入的特点,某个线程得到对象的锁后,再次请求此对象可以再次得到改对象的锁.如下示例,在method1中调用method2,在method2中调用method3,而met ...

  9. 架构师养成记--34.Redis持久化

    ---恢复内容开始--- redis是一个支持持久化的内存数据库,也就是搜redis需要经常将内存中的数据同步到硬盘来保证持久化.redis持久化有两种方式. snapshotting(快照)默认方式 ...

随机推荐

  1. java web学习总结(二十八) -------------------JSP中的JavaBean

    一.什么是JavaBean JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法 ...

  2. Java 内存区域与内存溢出

    内存区域 Java 虚拟机在执行 Java 程序的过程中会把他所管理的内存划分为若干个不同的数据区域.Java 虚拟机规范将 JVM 所管理的内存分为以下几个运行时数据区:程序计数器.Java 虚拟机 ...

  3. JQuery操作类数组的工具方法

    JQuery学习之操作类数组的工具方法 在很多时候,JQuery的$()函数都返回一个类似数据的JQuery对象,例如$('div')将返回div里面的所有div元素包装的JQuery对象.在这中情况 ...

  4. 菜鸟快飞之JavaScript对象、原型、继承(三)

    正文之前需要声明的一点是,菜鸟系列博文全是基于ES5的,不考虑ES6甚至更高版本. 继承 由于我个人不是学计算机的,所以对于很多东西只是知其然,不知其所以然.就像这个继承,刚开始学JavaScript ...

  5. javascript的defer和async的区别。

    我们常用的script标签,有两个和性能.js文件下载执行相关的属性:defer和async defer的含义[摘自https://developer.mozilla.org/En/HTML/Elem ...

  6. CRM sql 查询

    转自博友"菜刀-soft"! 查询实体信息: --查询实体信息,实体名称:account select * from MetadataSchema.Entity where nam ...

  7. 磨刀不误砍柴工——VS生成事件

    如果说磨刀不误砍柴工,同样用好Visual Studio,会大大增加咱.NET程序猿效率.本文说的就是Visual Studio中的生成事件,在解决方案下右击某个项目然后选择 “属性” 打开窗口后即可 ...

  8. gulp入门小记

    由于我所在的项目组一直在用gulp构建工具,而我只是在前人搭好的环境下每次运行gulp packJs来打包js,对里面的东西全然不知,刚好最近有些时间就想自己从学学将gulp怎么用于构建前端项目中,这 ...

  9. React Native APP结构探索

    APP结构探索 我在Github上找到了一个有登陆界面,能从网上获取新闻信息的开源APP,想来研究一下APP的结构. 附上原网址:我的第一个React Native App 具体来讲,就是研究一个复杂 ...

  10. xml节点查询

    关键词: XName XElement Descendance() node.Name.LocalName 示范: List<ClaimSheetBaseDto> list = new L ...