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模式讲解(一)的更多相关文章

  1. 多线程集成设计模式--future模式

    多线程开发可以更好的发挥多核cpu性能,常用的多线程设计模式有:Future.Master-Worker.Guard Susperionsion 一.什么是Future模型: 该模型是将异步请求和代理 ...

  2. 14.多线程设计模式 - Master-Worker模式

    多线程设计模式 - Master-Worker模式 并发设计模式属于设计优化的一部分,它对于一些常用的多线程结构的总结和抽象.与串行相比并行程序结构通常较为复杂,因此合理的使用并行模式在多线程并发中更 ...

  3. 并行程序设计模式--Master-Worker模式

    简介 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进程负责接收和分配任务,Worker进程负责处理子任务 ...

  4. 转 Master-Worker模式 并行程序设计模式--Master-Worker模式

    简介 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进程负责接收和分配任务,Worker进程负责处理子任务 ...

  5. 多线程设计模式 : Master-Worker模式

    Master-Worker是常用的并行计算模式.它的核心思想是系统由两类进程协作工作:Master进程和Worker进程.Master负责接收和分配任务,Worker负责处理子任务.当各个Worker ...

  6. 多线程的设计模式--Future模式,Master-Worker模式,生产者-消费者模式

    代码示例: public interface Data { String getRequest(); } public class FutureData implements Data{ privat ...

  7. Java多线程编程中Future模式的详解

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  8. Java多线程编程中Future模式的详解<转>

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  9. Master-Worker模式

    并行程序设计模式--Master-Worker模式 简介 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进 ...

随机推荐

  1. 同步锁Lock & 生产者和消费者案例

    显示锁 Lock ①在 Java 5.0 之前,协调共享对象的访问时可以使用的机 制只有 synchronized 和 volatile . Java 5.0 后增加了一些 新的机制,但并不是一种替代 ...

  2. 01 . Redis简介及部署主从复制

    简介 Remote Dictionary Server, 翻译为远程字典服务, Redis是一个完全开源的基于Key-Value的NoSQL存储系统,他是一个使用ANSIC语言编写的,遵守BSD协议, ...

  3. JavaScript (六) js的基本语法 - - - Math 及 Date对象、String对象、Array对象

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.Math 1.Math对象的案例 var result= Math.max(10,20,30,40) ...

  4. Java实现 LeetCode 733 图像渲染(DFS)

    733. 图像渲染 有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间. 给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的 ...

  5. Java实现 LeetCode 443 压缩字符串

    443. 压缩字符串 给定一组字符,使用原地算法将其压缩. 压缩后的长度必须始终小于或等于原数组长度. 数组的每个元素应该是长度为1 的字符(不是 int 整数类型). 在完成原地修改输入数组后,返回 ...

  6. Java实现 蓝桥杯 算法训练 字符串合并

    试题 算法训练 字符串合并 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 输入两个字符串,将其合并为一个字符串后输出. 输入格式 输入两个字符串 输出格式 输出合并后的字符串 样例 ...

  7. Linux 自动挂载与fstab文件修复

    /etc/fstab文件 自动挂载就是写入/etc/fstab文件 vi /etc/fstab 其中,第九行是/分区的自动挂载信息,有6个字段 第一字段表示分区的UUID(硬盘通用唯一识别码,使用du ...

  8. 源码分析(5)-ArrayList、Vector和LinkedList(JDK1.8)

    一.概述 1.线程安全:ArrayList和LinkedList非线程安全的.Vector线程安全的. 2.底层数据结构:ArrayList和Vector底层数据结构是数组:LinkedList双向链 ...

  9. 本地配置gitee

    一 下载工具 Git-2.62.0-64-bit.exe 以上工具版本号不需要一样,安装完前两个后重新启动系统,再安装第3个. 二 码云网站注册 https://gitee.com/ 使用邮箱注册 注 ...

  10. Redis Desktop Manager无法连接虚拟机中启动的redis服务问题排查步骤

    Redis Desktop Manager下载地址 https://redisdesktop.com/download 安装好以后连接linux服务器上的Redis服务器错误: 问题排查: 1.检查R ...