简易的Master-Worker框架
Master-Worker模式是一种使用多线程进行数据处理的结构,多个worker进程协作处理用户请求,master进程负责维护worker进程,并整合最终处理结果
主要参与者
- Worker:用于实际处理一个任务
- Master:用于任务的分配和最终结果的合成
- Main:启动系统,调度开启Master
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
/**
* Master进程负责接收和分配任务
*/
public class Master {
//子任务队列 ConcurrentLinkedDeque:双向链表结构的无界并发队列
protected Queue<Object> workQueue = new ConcurrentLinkedDeque<>();
//worker进程队列
protected Map<String,Thread> threadMap = new HashMap<>();
//子任务处理结果集
protected Map<String,Object> resultMap = new ConcurrentHashMap<>();
//是否所以的子任务都结束了
public boolean isComplete(){
for (Map.Entry<String, Thread> entry : threadMap.entrySet()) {
//停止状态
if (entry.getValue().getState()!= Thread.State.TERMINATED){
return false;
}
}
return true;
}
// Worker进程,Worker进程数量
public Master(Worker worker, int countWorker) {
worker.setWorkQueue(workQueue);
worker.setResultMap(resultMap);
for (int i = 0; i < countWorker; i++) {
threadMap.put(Integer.toString(i),new Thread(worker,Integer.toString(i)));
}
}
//提交一个任务
public void submit(Object job){
workQueue.add(job);
}
//返回子任务结果集
public Map<String, Object> getResultMap() {
return resultMap;
}
//运行所以Worker进程,进行处理
public void execute(){
for (Map.Entry<String, Thread> entry : threadMap.entrySet()) {
entry.getValue().start();
}
}
}
import java.util.Map;
import java.util.Queue;
/**
* Worker进程负责处理子任务
*/
public class Worker implements Runnable {
//子任务队列
protected Queue<Object> workQueue;
//子任务处理结果集
protected Map<String,Object> resultMap;
public void setWorkQueue(Queue<Object> workQueue) {
this.workQueue = workQueue;
}
public void setResultMap(Map<String, Object> resultMap) {
this.resultMap = resultMap;
}
//子任务处理的逻辑,在子类中实现具体逻辑
public Object handle(Object input){
return input;
}
@Override
public void run() {
while (true){
//获取子任务
Object input = workQueue.poll();
if (input==null) break;
//处理子任务
Object re = handle(input);
//将处理结果写入结果集
resultMap.put(Integer.toString(input.hashCode()),re);
}
}
}
/**
* 任务 求 i^2
*/
public class PlusWorker extends Worker {
public Object handle(Object input){
Integer i = (Integer) input;
return i*i;
}
}
import java.util.Map;
import java.util.Set;
/**
* 求 1^2 + 2^2 + 3^2 + 4^2 + 5^2
* 1 + 4 + 9 + 16 + 25 = 55
*/
public class Main {
public static void main(String[] args){
Master m = new Master(new PlusWorker(),5);
for (int i = 1; i <= 5; i++) {
m.submit(i);
}
m.execute();
int re = 0;
Map<String, Object> resultMap = m.getResultMap();
// 任务结果相加
while (resultMap.size()>0||!m.isComplete()){
Set<String> keys = resultMap.keySet();
String key = null;
for (String k : keys) { //每次只取一次
key = k;
break;
}
Integer i = null;
if (key!=null){
i = (Integer) resultMap.get(key);
}
if (i!=null){
re+=i; //任务结果相加
}
if (key!=null){
resultMap.remove(key); //移除已经被计算的结果项
}
}
System.out.println(re); //55
}
}
简易的Master-Worker框架的更多相关文章
- 简易对象垃圾回收框架 for Delphi
(一).缘起 1.1 我的一个出错程序 程序名称:呼叫处理模块的压力测试工具,分为客户端和服务端. 开发工具:Delhpi 5 相关技术:客户端通过与服务端建立Socket连接来模拟一组电话机的拨入. ...
- 依赖注入[5]: 创建一个简易版的DI框架[下篇]
为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在<依赖注入[4]: 创建一个简易版的DI框架[上篇]> ...
- 依赖注入[4]: 创建一个简易版的DI框架[上篇]
本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章(<控制反转>.<基于IoC的设计模式>和< 依赖注入模式>)从纯理论的角度 ...
- .NET CORE学习笔记系列(2)——依赖注入[4]: 创建一个简易版的DI框架[上篇]
原文https://www.cnblogs.com/artech/p/net-core-di-04.html 本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章从 ...
- 从零开始实现一个简易的Java MVC框架(三)--实现IOC
Spring中的IOC IoC全称是Inversion of Control,就是控制反转,他其实不是spring独有的特性或者说也不是java的特性,他是一种设计思想.而DI(Dependency ...
- 使用 js 实现一个简易版的 vue 框架
使用 js 实现一个简易版的 vue 框架 具有挑战性的前端面试题 refs https://www.infoq.cn/article/0NUjpxGrqRX6Ss01BLLE xgqfrms 201 ...
- 基于OpenGL编写一个简易的2D渲染框架-05 渲染文本
阅读文章前需要了解的知识:文本渲染 https://learnopengl-cn.github.io/06%20In%20Practice/02%20Text%20Rendering/ 简要步骤: 获 ...
- 基于OpenGL编写一个简易的2D渲染框架-01 创建窗口
最近正在学习OpenGL,我认为学习的最快方法就是做一个小项目了. 如果对OpenGL感兴趣的话,这里推荐一个很好的学习网站 https://learnopengl-cn.github.io/ 我用的 ...
- .NET CORE学习笔记系列(2)——依赖注入[5]: 创建一个简易版的DI框架[下篇]
为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在上篇中我们介绍了Cat的基本编程模式,接下来我们就来聊聊Cat的 ...
- 基于OpenGL编写一个简易的2D渲染框架-06 编写一个粒子系统
在这篇文章中,我将详细说明如何编写一个简易的粒子系统. 粒子系统可以模拟许多效果,下图便是这次的粒子系统的显示效果.为了方便演示,就弄成了一个动图. 图中,同时显示了 7 种不同粒子效果,看上去效果挺 ...
随机推荐
- JSP页面中<%!%>与<%%>与<%=%>详解
首先,我们要了解jsp运行原理.JSP的本质就是一个Servlet,JSP的运行之前会先被Tomcat服务器翻译为.java文件,然后在将.java文本编译 为.class文件,而我们在访问jsp时, ...
- Spring Transaction Isolation
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11530702.html Reference http://docs.spring.io/spring/ ...
- 别人的双11 & 程序员的双11~
双11,致敬所有的程序员欧巴! 愿代码的世界,只有爱,没有伤害!! 点此参加阿里云双十一拼团活动:https://m.aliyun.com/act/team1111/ 阅读原文
- SCJP读书之知识点:
1:实例变量和局部变量 实例变量:是在类中进行声明的,可以有public,private等修饰符进行修饰. 局部变量:在方法中进行声明,生命周期就是方法开始,到方法结束.但是可以进行对象的引用来调用. ...
- php ltrim()函数 语法
php ltrim()函数 语法 ltrim()函数怎么用? php ltrim()函数用于删除字符串左边的空格或其他预定义字符,语法是ltrim(string,charlist),返回经过charl ...
- python-zx笔记2-help
在cmd运行 查看模块的方法: help—查看模块的函数 1 help()
- rabbitmqctl常用命令-3
1)启动.关闭 rabbitmq节点和应用 rabbitmq-server -detached #rabbitmq分别启动节点和应用 应用关闭rabbitmqctl stop_app 应用启动 rab ...
- XX-net https://github.com/XX-net/XX-Net
XX-net https://github.com/XX-net/XX-Net
- 【玩转SpringBoot】异步任务执行与其线程池配置
同步代码写起来简单,但就是怕遇到耗时操作,会影响效率和吞吐量. 此时异步代码才是王者,但涉及多线程和线程池,以及异步结果的获取,写起来颇为麻烦. 不过在遇到SpringBoot异步任务时,这个问题就不 ...
- JS中获取元素使用getElementByID()、getElementsByName()、getElementsByTagName()的用法和区别
Web标准下可以通过getElementById(), getElementsByName(), and getElementsByTagName()访问Documnent中的任一个标签: 1 g ...