架构师养成记--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(快照)默认方式 ...
随机推荐
- Maven远程仓库的配置
在很多情况下,默认的中央仓库无法满足项目的需求,可能项目需要的构件存在于另外一个远程仓库中,如JBoss Maven仓库.这时,可以在POM中配置该仓库,见代码如下: <!-- 远程仓库的配置 ...
- spring四种依赖注入方式
一.Set注入 这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringD ...
- jdk jre jvm 三者之间关系
JDK JDK是java开发工具包,是Sun公司针对Java开发员的产品. JDK 中包含JRE,在JDK安装的目录下有一个叫jre的目录,里面有两个文件夹,bin/和lib,其中bin就是j ...
- JS正则表达式(JavaScript regular expression)
RegExp直接量和对象的创建 就像字符串和数字一样,程序中每个取值相同的原始类型直接量均表示相同的值,这是显而易见的.程序运行时每次遇到对象直接量(初始化表达式)诸如{}和[]的时候都会创建新对象. ...
- 利用github pages创建简单的网站
github.com 作为最流行的源代码管理工具已经风靡全球,同时在依托于github也衍生出了各种各样的应用,比如可以利用github搭建博客系统等等. 先换个话题,我们每人手头都或多或少有些&qu ...
- Android任务栈的运行规律
一:前台栈表示应用A,后台栈则是应用B 前台栈/taskAffinity/launchMode 后台栈/taskAffinity/launchMode ActivityB/com.lpn.teston ...
- iOS 开发者账号到期续费流程
1.登录developer.apple.com,查看到期时间 2.到期提醒通知,点击Renew Membership续费(一般提前一个月提醒续费) 3.个人开发者账号续费需要支付 688人民币/年(9 ...
- iOS 小谈开发者中的个人、组织(公司、企业)账号
苹果对开发者主要分为3类:个人.组织(公司.企业).教育机构.即: 1.个人(Individual) 2.组织(Organizations) 组织类又分为2个小类: (1)公司(Company) (2 ...
- swift-字典
swift字典 在swift中,key:key值一定是可hash的,一定是独一无二的,swift的基本数据类型(String,Int,Float)都是可哈希的,所以都可以作为key值. value:没 ...
- java实现敏感词过滤(DFA算法)
小Alan在最近的开发中遇到了敏感词过滤,便去网上查阅了很多敏感词过滤的资料,在这里也和大家分享一下自己的理解. 敏感词过滤应该是不用给大家过多的解释吧?讲白了就是你在项目中输入某些字(比如输入xxo ...