java线程模型Master-Worker
这样的模型是最经常使用的并行模式之中的一个,在Nginx源代码中有涉及到有想看的能够去这个大神的博客了解一下http://blog.csdn.net/marcky/article/details/6014733,这位大神写的有些简洁。
从思想的角度来说。它主要由两类进程进行协作:各自是Master进程和Worker进程。Master进程负责接受和分配任务,Worker进程负责处理子任务,当Worker将子任务处理完毕后。将结果返回给Master进程。由Master进程做归纳和汇总。得到终于结果。详细流程能够看此图
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmVadW5TaGFv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
这样的模式可以将一个大任务分解成若干个小任务去运行,适合一些耗时比較久的任务,可以提高系统的吞吐量。
一个相对完整的模型应该具备下面功能
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmVadW5TaGFv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
在借鉴了java性能优化书上的列子。上面实现了一个简单的Master-Worker模式
- package com.thread;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.Queue;
- import java.util.Set;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentLinkedDeque;
- public class Master_Worker {
- public static void main(String args[])
- {
- long start = System.currentTimeMillis();
- Master_Worker master_Worker = new Master_Worker(new PlusWorker(), 11);
- for (int i = 0; i < 100; i++) {
- master_Worker.submit(i);
- }
- master_Worker.execute();
- int re = 0;
- Map<String, Object> result_Map = master_Worker.getResultMap();
- while (result_Map.size()>0||!master_Worker.isComplete()) {
- Set<String> keysSet = result_Map.keySet();
- String keyString = null;
- for (String string : keysSet) {
- keyString = string;
- break;
- }
- Integer i = null;
- if (keyString !=null) {
- i = (Integer) result_Map.get(keyString);
- }
- if (i!=null) {
- re+=i;
- }
- if (keyString!=null) {
- result_Map.remove(keyString);
- }
- }
- long end = System.currentTimeMillis();
- System.out.println("结果:"+re+"-运行之间"+(end-start));
- int sum = 0;
- start = System.currentTimeMillis();
- for (int i = 1; i <= 100; i++) {
- sum+=i*i*i;
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- end = System.currentTimeMillis();
- System.out.println("结果:"+sum+"-运行之间"+(end-start));
- }
- // 任务队列
- protected Queue<Object> workerQueue = 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;
- }
- // Master的构造,须要一个Worker进程逻辑,和须要的Worker进程数量
- public Master_Worker(Worker woker, int countWorker) {
- woker.setWorkQueue(workerQueue);
- woker.setResultMap(resultMap);
- for (int i = 0; i < countWorker; i++) {
- threadMap.put(Integer.toString(i),
- new Thread(woker, Integer.toString(i)));
- }
- }
- //返回子任务结果集
- public Map<String, Object> getResultMap()
- {
- return resultMap;
- }
- //提交任务
- public void submit(Object job) {
- workerQueue.add(job);
- }
- public void execute()
- {
- for (Map.Entry<String, Thread> entry : threadMap.entrySet()) {
- if (entry.getValue().getState() != Thread.State.TERMINATED) {
- entry.getValue().start();
- }
- }
- }
- }
- 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() {
- // TODO Auto-generated method stub
- while (true) {
- // 获取子任务
- Object inputObject = workQueue.poll();
- if (inputObject == null) {
- break;
- }
- // 处理子任务
- Object reObject = handle(inputObject);
- resultMap.put(Integer.toString(inputObject.hashCode()), reObject);
- }
- }
- }
- /*
- * 扩展自己的类
- * */
- class PlusWorker extends Worker{
- @Override
- public Object handle(Object input) {
- // TODO Auto-generated method stub
- //在这里能够自己实现自己的业务逻辑等,在这里我让线程睡眠了100毫秒,模拟任务运行
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- Integer i = (Integer) input;
- return i*i*i;
- }
- }
这里的大多数都是借鉴java性能优化一书,加上自己的改编和简单介绍。
java线程模型Master-Worker的更多相关文章
- eventloop & actor模式 & Java线程模型演进 & Netty线程模型 总结
eventloop的基本概念可以参考:http://www.ruanyifeng.com/blog/2013/10/event_loop.html Eventloop指的是独立于主线程的一条线程,专门 ...
- 1、java线程模型
要了解多线程,先需要把java线程模型搞清楚,否则有时候很难理清楚一个问题. 硬件多线程: 物理机硬件的并发问题跟jvm中的情况有不少相似之处,物理机的并发处理方案对于虚拟机也有相当大的参考意义.在买 ...
- JS线程模型&Web Worker
js线程模型 客户端javascript是单线程,浏览器无法同时运行两个事件处理程序 设计为单线程的理论是,客户端的javascript函数必须不能运行太长时间,否则会导致web浏览器无法对用户输入做 ...
- Java线程模型
并发不一定要依赖多线程(如PHP中很常见的多进程并发),但是在Java里面谈论并发,大多数都与线程脱不开关系. 线程是比进程更轻量级的调度执行单位,线程的引入,可以把一个进程的资源分配和执行调度分开, ...
- java线程基础知识----java线程模型
转载自http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html 1. 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标 ...
- java并发笔记之java线程模型
警告⚠️:本文耗时很长,先做好心理准备 java当中的线程和操作系统的线程是什么关系? 猜想: java thread —-对应-—> OS thread Linux关于操作系统的线程控制源码: ...
- 七. 多线程编程2.Java线程模型
Java运行系统在很多方面依赖于线程,所有的类库设计都考虑到多线程.实际上,Java使用线程来使整个环境异步.这有利于通过防止CPU循环的浪费来减少无效部分. 为更好的理解多线程环境的优势可以将它与它 ...
- 理解微信小程序的双线程模型
有过微信小程序开发经验的朋友应该都知道"双线程模型"这个概念,本文简单梳理一下双线程模型的一些科普知识,学识浅薄,若有错误欢迎指正. 我以前就职于「小程序·云开发」团队,在对外的一 ...
- 【转载】 Java线程面试题 Top 50
Java线程面试题 Top 50 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员 的欢迎.大多数待遇丰厚的J ...
随机推荐
- 检查点--JMeter也有之二“检查点”
检查点:简单的来理解一下,上一章讲到,我们对用户名和密码进行了参数化,那么怎样来判断jmeter有没有正确调用test.dat里面的文件呢.当然,我们可以从结果图表中查看.但我还是想在“登录”这个地方 ...
- Request.Url.Port 获取不到正确的端口号
今天遇到一个很奇怪的事情,用request.url.port来获取一个请求的端口,返回是80 ,很纳闷啊我的请求上面是http://www.XX.com:8088 啊,怎么会是80啊,太不可思议了! ...
- The Art of Mocking
One of the challenges developers face when writing unit tests is how to handle external dependencies ...
- ios frame,bound和center
frame:指的是视图在父视图的坐标系统中的大小和位置. bound:指的是视图在试图本身的坐标系统中的大小(位置起点是原点). center:指的是视图在父视图坐标系统中的中心点. 贴张苹果官网的图 ...
- 常用VBA小技巧
用对话框选取文件路径(单个文件) 删除导入csv等文本文件后留下的 Data connections 增加新的工作表并并命名 Worksheets.Add(After:=Worksheets(Work ...
- JAVA常见算法题(十八)
package com.xiaowu.demo; /** * 两个乒乓球队进行比赛,各出三人.甲队为a,b,c三人,乙队为x,y,z三人,以抽签决定比赛名单. 有人向队员打听比赛的名单:a说他不和x比 ...
- ES6中关于数据类型的拓展:Symbol类型
ES5中包含5种原始类型:字符串.数值.布尔值.null.undefined.ES6引入了第6种原始类型——Symbol. ES5的对象属性名都是字符串,很容易造成属性名冲突.比如,使用了一个他人提供 ...
- 一个基于RSA算法的Java数字签名例子
原文地址:一个基于RSA算法的Java数字签名例子 一.前言: 网络数据安全包括数据的本身的安全性.数据的完整性(防止篡改).数据来源的不可否认性等要素.对数据采用加密算法加密可以保证数据本身的安全性 ...
- 机器学习第3课:线性代数回顾(Linear Algebra Review)
3.1 矩阵和向量 如图:这个是 4×2 矩阵,即 4 行 2 列,如 m 为行,n 为列,那么 m×n 即 4×2 矩阵的维数即行数×列数 矩阵元素(矩阵项): Aij 指第 i 行,第 j 列的 ...
- Linux查看目录大小
du -ah --max-depth=1 a表示显示目录下所有的文件和文件夹(不含子目录) h表示以人类能看懂的方式 max-depth表示目录的深度