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. Maven远程仓库的配置

    在很多情况下,默认的中央仓库无法满足项目的需求,可能项目需要的构件存在于另外一个远程仓库中,如JBoss Maven仓库.这时,可以在POM中配置该仓库,见代码如下: <!-- 远程仓库的配置 ...

  2. spring四种依赖注入方式

    一.Set注入 这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringD ...

  3. jdk jre jvm 三者之间关系

    JDK JDK是java开发工具包,是Sun公司针对Java开发员的产品.     JDK 中包含JRE,在JDK安装的目录下有一个叫jre的目录,里面有两个文件夹,bin/和lib,其中bin就是j ...

  4. JS正则表达式(JavaScript regular expression)

    RegExp直接量和对象的创建 就像字符串和数字一样,程序中每个取值相同的原始类型直接量均表示相同的值,这是显而易见的.程序运行时每次遇到对象直接量(初始化表达式)诸如{}和[]的时候都会创建新对象. ...

  5. 利用github pages创建简单的网站

    github.com 作为最流行的源代码管理工具已经风靡全球,同时在依托于github也衍生出了各种各样的应用,比如可以利用github搭建博客系统等等. 先换个话题,我们每人手头都或多或少有些&qu ...

  6. Android任务栈的运行规律

    一:前台栈表示应用A,后台栈则是应用B 前台栈/taskAffinity/launchMode 后台栈/taskAffinity/launchMode ActivityB/com.lpn.teston ...

  7. iOS 开发者账号到期续费流程

    1.登录developer.apple.com,查看到期时间 2.到期提醒通知,点击Renew Membership续费(一般提前一个月提醒续费) 3.个人开发者账号续费需要支付 688人民币/年(9 ...

  8. iOS 小谈开发者中的个人、组织(公司、企业)账号

    苹果对开发者主要分为3类:个人.组织(公司.企业).教育机构.即: 1.个人(Individual) 2.组织(Organizations) 组织类又分为2个小类: (1)公司(Company) (2 ...

  9. swift-字典

    swift字典 在swift中,key:key值一定是可hash的,一定是独一无二的,swift的基本数据类型(String,Int,Float)都是可哈希的,所以都可以作为key值. value:没 ...

  10. java实现敏感词过滤(DFA算法)

    小Alan在最近的开发中遇到了敏感词过滤,便去网上查阅了很多敏感词过滤的资料,在这里也和大家分享一下自己的理解. 敏感词过滤应该是不用给大家过多的解释吧?讲白了就是你在项目中输入某些字(比如输入xxo ...