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 ...
随机推荐
- docker网络及Dockerfile
1.制作镜像 使用阿里的yum源,网址:https://opsx.alibaba.com/mirror,或者mirrors.aliyun.com,点击帮助,就会有弹框出来. docker pull c ...
- cannot be cast to javassist.util.proxy.Proxy
工程lib冲突 javassist-3.18.1-GA.jar javassist-3.11.0.GA.jar 删除一个
- (转)Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)
http://www.xuanyusong.com/archives/1427 异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通 ...
- jsp homework(*)
3.编写一个JSP程序实现手表的功能,显示当前时间(时:分:秒),并不停地自动刷新时间. 方法一[scriptlet] <%@ page language="java" im ...
- Linux CURL的安装
Linux CURL的安装 Linux CURL的安装 --获得安装包,从网上直接下载或者其他途径,这里直接wget# wget http://curl.haxx.se/download/cur ...
- linux-系统资源查看-动态
1.top 2.sar http://blog.csdn.net/hguisu/article/details/7493661 很重要 http://blog.itpub.net/24435147/ ...
- Windows下将ISO镜像制作成U盘启动的工具(U盘启动工具/UltraISO/Rufus/Universal-USB)
说明:基于Windows的U盘启动制作都是非常的简单,在软件上指定ISO文件之后,一般都是选择写入到哪个U盘即可. 1.UltraISO 2.Rufus 3.Universal-USB 4.大白菜
- androd 获得wifi列表
AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xm ...
- depth linear
float ConvertDepth( float depthFromTex, float4 cameraParams ){ const float near = cameraParams.z; co ...
- Vue计算属性和监听属性
一.计算属性 计算属性关键词: computed.计算属性在处理一些复杂逻辑时是很有用的. 可以看下以下反转字符串的例子: <div id="app"> {{ mess ...