架构师养成记--10.master-worker模式
master-worker模式是一种并行计算模式,分为master进程和worker进程两个部分,master是担任总管角色,worker才是执行具体任务的地方。
总体流程应该是这样的:
具体一点,代码实现流程应该是这样的:
client:
- import java.util.Random;
- public class Main {
- public static void main(String[] args) {
- Master master = new Master(new Worker(), 20);//并发数20,也就是有20个Worker在工作
- Random r = new Random();
- for(int i = 1; i <= 100; i++){//总共有100个任务
- Task t = new Task();
- t.setId(i);
- t.setPrice(r.nextInt(1000));
- master.submit(t);//提交任务,向WorkerQueue<Task> 中加入元素
- }
- master.execute();//启动所有的worker
- long start = System.currentTimeMillis();
- while(true){
- if(master.isComplete()){//100个任务执行完成
- long end = System.currentTimeMillis() - start;
- int priceResult = master.getResult();//获取所有任务的执行结果
- System.out.println("最终结果:" + priceResult + ", 执行时间:" + end);
- break;
- }
- }
- }
- }
Master:
- 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);
- 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;
- }
Worker:
- 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;
- }
- }
Task:
- 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;
- }
- }
架构师养成记--10.master-worker模式的更多相关文章
- 架构师养成记--9.future模式讲解
什么是future模式呢?解释这个概念之前我们先来了解一个场景吧,财务系统的结账功能,这个功能可能是每个月用一次,在这一个月中相关的数据量已经积累得非常大,这一个功能需要调用好几个存储过程来完成.假如 ...
- 架构师养成记--35.redis集群搭建
前记:redis哨兵经验之谈.哨兵做主从切换可能要花费一两秒,这一两秒可能会丢失很多数据.解决方法之一是在java代码中做控制,try catch 到 链接断开的异常就sleep 一两秒钟再conti ...
- 架构师养成记--11.Executor概述
常用方法 Executors.newFiexdPool(int nThreads);固定线程数量的线程池: Executors.newSingleThreadExecutor();单个线程的线程池: ...
- 架构师养成记--8.Queue
一.ConcurrentLinkedQueue 是一个适合在高并发场景下,无锁,无界的,先进先出原则.不允许为null值,add().offer()加入元素,这两个方法没区别:pull().peek( ...
- 架构师养成记--15.Disruptor并发框架
一.概述 disruptor对于处理并发任务很擅长,曾有人测过,一个线程里1s内可以处理六百万个订单,性能相当感人. 这个框架的结构大概是:数据生产端 --> 缓存 --> 消费端 缓存中 ...
- 架构师养成记--6.单例和多线程、ThreadLocal
一.ThreadLocal 使用wait/notify方式实现的线程安全,性能将受到很大影响.解决方案是用空间换时间,不用锁也能实现线程安全. 来看一个小例子,在线程内的set.get就是thread ...
- 架构师养成记--4.volatile关键字
volatile修饰的变量可在多个线程间可见. 如下代码,在子线程运行期间主线程修改属性值并不对子线程产生影响,原因是子线程有自己独立的内存空间,其中有主内存中的变量副本. public class ...
- 架构师养成记--3.synchronized细节问题
一.synchronized有锁重入的特点,某个线程得到对象的锁后,再次请求此对象可以再次得到改对象的锁.如下示例,在method1中调用method2,在method2中调用method3,而met ...
- 架构师养成记--34.Redis持久化
---恢复内容开始--- redis是一个支持持久化的内存数据库,也就是搜redis需要经常将内存中的数据同步到硬盘来保证持久化.redis持久化有两种方式. snapshotting(快照)默认方式 ...
随机推荐
- java web学习总结(二十八) -------------------JSP中的JavaBean
一.什么是JavaBean JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法 ...
- Java 内存区域与内存溢出
内存区域 Java 虚拟机在执行 Java 程序的过程中会把他所管理的内存划分为若干个不同的数据区域.Java 虚拟机规范将 JVM 所管理的内存分为以下几个运行时数据区:程序计数器.Java 虚拟机 ...
- JQuery操作类数组的工具方法
JQuery学习之操作类数组的工具方法 在很多时候,JQuery的$()函数都返回一个类似数据的JQuery对象,例如$('div')将返回div里面的所有div元素包装的JQuery对象.在这中情况 ...
- 菜鸟快飞之JavaScript对象、原型、继承(三)
正文之前需要声明的一点是,菜鸟系列博文全是基于ES5的,不考虑ES6甚至更高版本. 继承 由于我个人不是学计算机的,所以对于很多东西只是知其然,不知其所以然.就像这个继承,刚开始学JavaScript ...
- javascript的defer和async的区别。
我们常用的script标签,有两个和性能.js文件下载执行相关的属性:defer和async defer的含义[摘自https://developer.mozilla.org/En/HTML/Elem ...
- CRM sql 查询
转自博友"菜刀-soft"! 查询实体信息: --查询实体信息,实体名称:account select * from MetadataSchema.Entity where nam ...
- 磨刀不误砍柴工——VS生成事件
如果说磨刀不误砍柴工,同样用好Visual Studio,会大大增加咱.NET程序猿效率.本文说的就是Visual Studio中的生成事件,在解决方案下右击某个项目然后选择 “属性” 打开窗口后即可 ...
- gulp入门小记
由于我所在的项目组一直在用gulp构建工具,而我只是在前人搭好的环境下每次运行gulp packJs来打包js,对里面的东西全然不知,刚好最近有些时间就想自己从学学将gulp怎么用于构建前端项目中,这 ...
- React Native APP结构探索
APP结构探索 我在Github上找到了一个有登陆界面,能从网上获取新闻信息的开源APP,想来研究一下APP的结构. 附上原网址:我的第一个React Native App 具体来讲,就是研究一个复杂 ...
- xml节点查询
关键词: XName XElement Descendance() node.Name.LocalName 示范: List<ClaimSheetBaseDto> list = new L ...