多线程集成设计模式--MasterWorker模式讲解(一)
Master-Worker模式是常用的并行模式之一,它的核心思想是,系统有两个进程协作工作:Master进程,负责接收和分配任务;Worker进程,负责处理子任务。当Worker进程将子任务处理完成后,结果返回给Master进程,由Master进程做归纳汇总,最后得到最终的结果。
一、什么是Master-Worker模式:
该模式的结构图:
Worker:用于实际处理一个任务;
Master:任务的分配和最终结果的合成;
Main:启动程序,调度开启Master。
注意点:
Master必须存在一个队列来存储客户端发送过来的任务,必须有一个队列,我们选择无阻塞无界队列
Worker实际处理任务的操作者,所以应该是线程,应该实现runnable接口
master应该有一个容器装所有的worker对象,不涉及到高并发,使用hashmap ,value就是worker对象
worker需要拥有master进程中的无阻塞无界队列的引用,用来获得任务进行处理
master是对worker处理的结果做归纳总结,所以需要有一个队列要保存worker处理的结果,要实现并发安全的ConcurrentHashMap
worker需要拥有ConcurrentHashMap的引用,把处理的结果存储在ConcurrentHashMap中,需要线程安全的
Master-Worker模式是一种将串行任务并行化的方案。
更重要的是提供了一种变化的思想。
我们来看下面程序的代码:
- package com.bjsxt.height.design015;
- public class Task {
- private int id;
- private int price ;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public int getPrice() {
- return price;
- }
- public void setPrice(int price) {
- this.price = price;
- }
- }
- package com.bjsxt.height.design015;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentLinkedQueue;
- public class Worker implements Runnable {
- private ConcurrentLinkedQueue<Task> workQueue;
- private ConcurrentHashMap<String, Object> resultMap;
- public void setWorkQueue(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);
- this.resultMap.put(Integer.toString(input.getId()), output);
- }
- }
- private Object handle(Task input) {
- Object output = null;
- try {
- //处理任务的耗时。。 比如说进行操作数据库。。。
- Thread.sleep(500);
- output = input.getPrice();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- return output;
- }
- }
- package com.bjsxt.height.design015;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentLinkedQueue;
- public class Master {
- //1 有一个盛放任务的容器
- private ConcurrentLinkedQueue<Task> workQueue = new ConcurrentLinkedQueue<Task>();
- //2 需要有一个盛放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.setWorkQueue(this.workQueue);
- worker.setResultMap(this.resultMap);
- /**
- * 初始化woker对象的个数,管理worker对象,开启100个worker对象,装到hashmap中
- * */
- for(int i = 0; i < workerCount; i ++){
- this.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 priceResult = 0;
- for(Map.Entry<String, Object> me : resultMap.entrySet()){
- priceResult += (Integer)me.getValue();
- }
- return priceResult;
- }
- }
- package com.bjsxt.height.design015;
- import java.util.Random;
- public class Main {
- public static void main(String[] args) {
- Master master = new Master(new Worker(), 20);
- Random r = new Random();
- for(int i = 1; i <= 100; i++){
- Task t = new Task();
- t.setId(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 priceResult = master.getResult();
- System.out.println("最终结果:" + priceResult + ", 执行时间:" + end);
- break;
- }
- }
- }
- }
程序运行的结果是:
最终结果:54386, 执行时间:2500
将每个worker计算得到的price结果进行相加
相当的经典,这种设计模式就是将串行化的思想转换成并行化进行处理
多线程集成设计模式--MasterWorker模式讲解(一)的更多相关文章
- 多线程集成设计模式--future模式
多线程开发可以更好的发挥多核cpu性能,常用的多线程设计模式有:Future.Master-Worker.Guard Susperionsion 一.什么是Future模型: 该模型是将异步请求和代理 ...
- 14.多线程设计模式 - Master-Worker模式
多线程设计模式 - Master-Worker模式 并发设计模式属于设计优化的一部分,它对于一些常用的多线程结构的总结和抽象.与串行相比并行程序结构通常较为复杂,因此合理的使用并行模式在多线程并发中更 ...
- 并行程序设计模式--Master-Worker模式
简介 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进程负责接收和分配任务,Worker进程负责处理子任务 ...
- 转 Master-Worker模式 并行程序设计模式--Master-Worker模式
简介 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进程负责接收和分配任务,Worker进程负责处理子任务 ...
- 多线程设计模式 : Master-Worker模式
Master-Worker是常用的并行计算模式.它的核心思想是系统由两类进程协作工作:Master进程和Worker进程.Master负责接收和分配任务,Worker负责处理子任务.当各个Worker ...
- 多线程的设计模式--Future模式,Master-Worker模式,生产者-消费者模式
代码示例: public interface Data { String getRequest(); } public class FutureData implements Data{ privat ...
- Java多线程编程中Future模式的详解
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- Java多线程编程中Future模式的详解<转>
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- Master-Worker模式
并行程序设计模式--Master-Worker模式 简介 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进 ...
随机推荐
- 慕零的黑夜-头条-第一期(必问)[导读:]1.CSDN必问赏金流向何方 2.CSDN必问偷偷做的手脚 3.CSDN必问靠谱吗 4.关于钱于回答的平衡问题:一美元拍卖骗局 作者:qq3461896724
本期是关于CSDN 必问 (biwen.csdn.net)的内容,欢迎评论 文末,文中插入有 小姐姐 img(附py代码,1.49G) + coding资料 哟~~~ 你看到这篇很可能是在提问.推荐加 ...
- jQuery 获取页面宽高
无滚动条的情况下(页面宽高比可视区域小):$(document)和$(window)的width.height方法获取的值都是一样的,都是可视区域的宽高即$(document).width()==$( ...
- PMP 冲!|项目整合管理
0x00概述 项目管理包括识别.定义.组合.统一与协调各项目管理过程组的过程及项目管理活动.包括在各个项目冲突的目标与方案之间进行权衡和选择. 整合管理包括进行如下选择: 资源分配: 平衡竞争性需求: ...
- 01 . Tomcat简介及部署
Tomcat简介 Tomcat背景 tomcat就是常用的的中间件之一,tomcat本身是一个容器,专门用来运行java程序,java语言开发的网页.jsp就应该运行于tomcat中.而tomcat本 ...
- Rocket - tilelink - toBools
https://mp.weixin.qq.com/s/UGMH8EoaVcFkkQW-l4HLWg 分析toBools在Intellij中显示为红色的问题. 1. 问题 在TLA ...
- 一招解决GitHub致命的下载速度(GitHub下载速度慢怎么办)
通过码云来导入github,通过码云下载 第一步: 找一个你需要下载的GitHub项目 第二步: 复制链接 第三步: 打开码云,然后选择从GitHub导入 第四步: 复制刚才的连接,起个名字,点击导入 ...
- Java实现 LeetCode 416 分割等和子集
416. 分割等和子集 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: ...
- java实现 洛谷 P1014 Cantor表
题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 1/5 - 2/1 2/2 2/3 2/4 - ...
- Java实现第九届蓝桥杯书号验证
书号验证 2004年起,国际ISBN中心出版了<13位国际标准书号指南>. 原有10位书号前加978作为商品分类标识:校验规则也改变. 校验位的加权算法与10位ISBN的算法不同,具体算法 ...
- SOA架构和微服务架构的区别与特点
1.SOA架构和微服务架构的区别 首先SOA和微服务架构一个层面的东西,而对于ESB和微服务网关是一个层面的东西,一个谈到是架构风格和方法,一个谈的是实现工具或组件. 1.SOA(Service Or ...