并发模型之Master-Worker设计模式
一、Master-Worker设计模式
Master-Worker模式是常用的并行设计模式。它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程。Master进程负责接收和分配任务,Worker进程负责处理子任务。当各个Worker进程将子任务处理完后,将结果返回给Master进程,由Master进行归纳和汇总,从而得到系统结果。
Master-Worker模式的好处是,它能将大任务分解成若干个小任务,并发执行,从而提高系统性能。而对于系统请求者Client来说,任务一旦提交,Master进程就会立刻分配任务并立即返回,并不会等系统处理完全部任务再返回,其处理过程是异步的。
二、Master-Worker设计模式代码实现
1、创建Task任务对象
package com.ietree.basicskill.mutilthread.designpattern.masterworker; /**
* Created by Root on 5/12/2017.
*/
public class Task { private int id; private String name; private int price; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getPrice() {
return price;
} public void setPrice(int price) {
this.price = price;
}
}
2、实现Worker对象
package com.ietree.basicskill.mutilthread.designpattern.masterworker; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue; /**
* Created by Root on 5/12/2017.
*/
public class Worker implements Runnable { private ConcurrentLinkedQueue<Task> workQueue;
private ConcurrentHashMap<String, Object> resultMap; public void setWorkerQueue(ConcurrentLinkedQueue<Task> workQueue) {
this.workQueue = workQueue;
} public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
this.resultMap = resultMap;
} @Override
public void run() {
while (true) {
Task input = this.workQueue.poll();
if (input == null) {
break;
}
// 真正的去做业务处理
//Object output = handle(input);
// 改造
Object output = MyWorker.handle(input);
// 返回处理结果集
this.resultMap.put(Integer.toString(input.getId()), output);
}
} // private Object handle(Task input) {
// Object output = null;
// try {
// // 表示处理task任务的耗时,可能是数据的加工,也可能是操作数据库......
// Thread.sleep(500);
// output = input.getPrice();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// return output;
// } // 优化,考虑让继承类去自己实现具体的业务处理
public static Object handle(Task input) {
return null;
} }
3、为了使程序更灵活,将具体的业务执行逻辑抽离,在具体的Worker对象去实现,如这里的MyWorker对象
package com.ietree.basicskill.mutilthread.designpattern.masterworker; /**
* Created by Root on 5/13/2017.
*/
public class MyWorker extends Worker { public static Object handle(Task input) {
Object output = null;
try {
// 表示处理task任务的耗时,可能是数据的加工,也可能是操作数据库......
Thread.sleep(500);
output = input.getPrice();
} catch (InterruptedException e) {
e.printStackTrace();
}
return output;
} }
4、Master类
package com.ietree.basicskill.mutilthread.designpattern.masterworker; import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue; /**
* Created by Root on 5/12/2017.
*/
public class Master { // 1、使用一个ConcurrentLinkedQueue集合来装载所有需要执行的任务
private ConcurrentLinkedQueue<Task> workQueue = new ConcurrentLinkedQueue<Task>(); // 2、使用HashMap来装载所有的worker对象
private HashMap<String, Thread> workers = new HashMap<String, Thread>(); // 3、使用一个容器承装每一个worker并发执行任务的结果集
private ConcurrentHashMap<String, Object> resultMap = new ConcurrentHashMap<String, Object>(); // 4、构造方法
public Master(Worker worker, int workerCount) {
// 每一个worker对象都需要有Master的引用,workQueue用于任务的领取,resultMap用于任务的提交
worker.setWorkerQueue(this.workQueue);
worker.setResultMap(this.resultMap); for (int i = 0; i < workerCount; i++) {
workers.put("子节点" + Integer.toString(i), new Thread(worker));
}
} // 5、提交方法
public void submit(Task task) {
this.workQueue.add(task);
} // 6、需要有一个执行的方法(启动应用程序,让所有的worker工作)
public void execute() {
for (Map.Entry<String, Thread> me : workers.entrySet()) {
me.getValue().start();
}
} // 7、判断线程是否执行完毕
public boolean isComplete() {
for (Map.Entry<String, Thread> me : workers.entrySet()) {
// 判断所有的线程状态是否属于已停止状态
if (me.getValue().getState() != Thread.State.TERMINATED) {
return false;
}
}
return true;
} // 8、返回结果集数据
public int getResult() {
int ret = 0;
for (Map.Entry<String, Object> me : resultMap.entrySet()) {
// 汇总逻辑
ret += (Integer) me.getValue();
}
return ret;
} }
5、测试,具体调用实现
package com.ietree.basicskill.mutilthread.designpattern.masterworker; import java.util.Random; /**
* Created by Root on 5/13/2017.
*/
public class MasterWorkerTest { public static void main(String[] args) { // Master master = new Master(new Worker(), 10);
// 改造
// Master master = new Master(new MyWorker(), 10);
// 改造(获取当前机器可用线程数)
System.out.println("我的机器可用Processors数量:" + Runtime.getRuntime().availableProcessors());
Master master = new Master(new MyWorker(), Runtime.getRuntime().availableProcessors()); Random r = new Random();
for (int i = 1; i <= 10; i++) {
Task t = new Task();
t.setId(i);
t.setName("任务" + i);
t.setPrice(r.nextInt(1000));
master.submit(t);
}
master.execute(); long start = System.currentTimeMillis(); while (true) {
if (master.isComplete()) {
long end = System.currentTimeMillis() - start;
int ret = master.getResult();
System.out.println("最终的结果:" + ret + ",执行耗时:" + end);
break;
}
}
} }
程序输出:
我的机器可用Processors数量:20
最终的结果:4473,执行耗时:500
从上面的运行结果来看,程序最终执行时间几乎就等于一个线程单独运行的时间,在此注意的是,同时执行的线程数是根据你执行此程序的机器配置决定的。
并发模型之Master-Worker设计模式的更多相关文章
- 一网打尽 Java 并发模型
本篇文章我们来探讨一下并发设计模型. 可以使用不同的并发模型来实现并发系统,并发模型说的是系统中的线程如何协作完成并发任务.不同的并发模型以不同的方式拆分任务,线程可以以不同的方式进行通信和协作. 并 ...
- nginx并发模型与traffic_server并发模型简单比较
ginx并发模型: nginx 的进程模型采用的是prefork方式,预先分配的worker子进程数量由配置文件指定,默认为1,不超过1024.master主进程创建监听套接口,fork子进程以后,由 ...
- memcached源码剖析4:并发模型
memcached是一个典型的单进程系统.虽然是单进程,但是memcached内部通过多线程实现了master-worker模型,这也是服务端最常见的一种并发模型.实际上,除了master线程和wor ...
- Java进阶7 并发优化2 并行程序设计模式
Java进阶7 并发优化2 并行程序设计模式20131114 1.Master-worker模式 前面讲解了Future模式,并且使用了简单的FutureTask来实现并发中的Future模式.下面介 ...
- 课堂笔记--Strom并发模型
Strom并发模型: topology是如何运行的?(可与mapreduce对比) 第一层:cluster 第二层:supervisor(host.node.机 ...
- 构建自己的Java并发模型框架
Java的多线程特性为构建高性能的应用提供了极大的方便,可是也带来了不少的麻烦.线程间同步.数据一致性等烦琐的问题须要细心的考虑,一不小心就会出现一些微妙的,难以调试的错误. 另外.应用逻辑和线程逻辑 ...
- 构建Java并发模型框架
Java的多线程特性为构建高性能的应用提供了极大的方便,但是也带来了不少的麻烦.线程间同步.数据一致性等烦琐的问题需要细心的考虑,一不小心就会出现一些微妙的,难以调试的错误.另外,应用逻辑和线程逻辑纠 ...
- Java并发模型框架
构建Java并发模型框架 Java的多线程特性为构建高性能的应用提供了极大的方便,但是也带来了不少的麻烦.线程间同步.数据一致性等烦琐的问题需要细心的考虑,一不小心就会出现一些微妙的,难以调试的错误. ...
- 并发模型与IO模型梳理
并发模型 常见的并发模型一般包括3类,基于线程与锁的内存共享模型,actor模型和CSP模型,其中尤以线程与锁的共享内存模型最为常见.由于go语言的兴起,CSP模型也越来越受关注.基于锁的共享内存模型 ...
随机推荐
- centos绑定https
1.百度云申请免费ssl证书 一年一申请 2. https://www.wosign .com /faq/faq-apache-https.htm 3.注意ssl.conf里面各个证书的顺序 证书路径 ...
- Linux 解压 压缩文件
来源于:http://blog.csdn.net/mmllkkjj/article/details/6768294/ 解压 tar –xvf file.tar //解压 tar包tar -xzvf f ...
- django入门-视图-part3
尊重作者的劳动,转载请注明作者及原文地址 http://www.cnblogs.com/txwsqk/p/6511384.html 完全翻译自官方文档 https://docs.djangoproje ...
- 【python】10分钟教你用python打造贪吃蛇超详细教程
10分钟教你用python打造贪吃蛇超详细教程 在家闲着没妹子约, 刚好最近又学了一下python,听说pygame挺好玩的.今天就在家研究一下, 弄了个贪吃蛇出来.希望大家喜欢. 先看程序效果: 0 ...
- Ubuntu 16.04防火墙
防火墙(ufw) 说明:简单版本的防火墙,底层依赖于iptables. 安装:sudo apt-get install ufw 查看状态:sudo ufw status 开启/关闭:sudo ufw ...
- (转)如何在CentOS / RHEL 7上安装Elasticsearch,Logstash和Kibana(ELK)
原文:https://www.howtoing.com/install-elasticsearch-logstash-and-kibana-elk-stack-on-centos-rhel-7 如果你 ...
- Spring Boot Starters是什么?
版权声明:该文转自: http://www.nosuchfield.com/2017/10/15/Spring-Boot-Starters/.版权归原创作者,在此对原作者的付出表示感谢! starte ...
- Qt Creator中使用qss对界面美化没有作用(效果)的问题
最近在研究qt界面开发,发现使用qss对界面进行美化后效果不错,要比mfc效率高很多,美化效果也很出色.但是在使用qss文件对界面控件进行美化的过程中遇到了个很奇葩的问题,困惑了我好久,今晚又遇到了, ...
- TimerJob无法发布新版本问题
最近遭遇发布TimerJob在测试环境发布没有问题,但是到正式环境发布总是无法执行及调试的问题,经过几天的努力,终于解决了这个问题,下面记录下遭遇的问题. Windows 2008,SharePoin ...
- vue2.0读书笔记2-进阶
一.深入响应式原理 二.过渡效果 三.过渡状态 四.Render函数 五.自定义指令 六.混合 七.插件 八.单文件组件 九.生产环境 十.路由 vue-router: http://router.v ...