这样的模型是最经常使用的并行模式之中的一个,在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的更多相关文章

  1. eventloop & actor模式 & Java线程模型演进 & Netty线程模型 总结

    eventloop的基本概念可以参考:http://www.ruanyifeng.com/blog/2013/10/event_loop.html Eventloop指的是独立于主线程的一条线程,专门 ...

  2. 1、java线程模型

    要了解多线程,先需要把java线程模型搞清楚,否则有时候很难理清楚一个问题. 硬件多线程: 物理机硬件的并发问题跟jvm中的情况有不少相似之处,物理机的并发处理方案对于虚拟机也有相当大的参考意义.在买 ...

  3. JS线程模型&Web Worker

    js线程模型 客户端javascript是单线程,浏览器无法同时运行两个事件处理程序 设计为单线程的理论是,客户端的javascript函数必须不能运行太长时间,否则会导致web浏览器无法对用户输入做 ...

  4. Java线程模型

    并发不一定要依赖多线程(如PHP中很常见的多进程并发),但是在Java里面谈论并发,大多数都与线程脱不开关系. 线程是比进程更轻量级的调度执行单位,线程的引入,可以把一个进程的资源分配和执行调度分开, ...

  5. java线程基础知识----java线程模型

    转载自http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html 1. 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标 ...

  6. java并发笔记之java线程模型

    警告⚠️:本文耗时很长,先做好心理准备 java当中的线程和操作系统的线程是什么关系? 猜想: java thread —-对应-—> OS thread Linux关于操作系统的线程控制源码: ...

  7. 七. 多线程编程2.Java线程模型

    Java运行系统在很多方面依赖于线程,所有的类库设计都考虑到多线程.实际上,Java使用线程来使整个环境异步.这有利于通过防止CPU循环的浪费来减少无效部分. 为更好的理解多线程环境的优势可以将它与它 ...

  8. 理解微信小程序的双线程模型

    有过微信小程序开发经验的朋友应该都知道"双线程模型"这个概念,本文简单梳理一下双线程模型的一些科普知识,学识浅薄,若有错误欢迎指正. 我以前就职于「小程序·云开发」团队,在对外的一 ...

  9. 【转载】 Java线程面试题 Top 50

    Java线程面试题 Top 50 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员 的欢迎.大多数待遇丰厚的J ...

随机推荐

  1. Python的程序结构[8] -> 装饰器/Decorator -> 装饰器浅析

    装饰器 / Decorator 目录 关于闭包 装饰器的本质 语法糖 装饰器传入参数 1 关于闭包 / About Closure 装饰器其本质是一个闭包函数,为此首先理解闭包的含义. 闭包(Clos ...

  2. String format -1 常规格式化

    常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的读者应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重 ...

  3. Quaternion Euler

    geometry_msgs::Quaternion orientation = map->info.origin.orientation;      tf::Matrix3x3 mat(tf:: ...

  4. mysql语法语句

    将一个字段中的timestamp修改成可视化时间 update table set f1 = IF( LOCATE('-',f1)>0, f1, IFNULL(FROM_UNIXTIME(f1/ ...

  5. VisualStudio Shell简介 — 集成插件

    Visual Studio Shell只是提供了一个内核,我们还需要在其基础上补充功能,从而实现我们自己的IDE.Visual Studio Shell的插件开发和Visual Studio插件开发是 ...

  6. zookeeper 学习笔记1(转)

    本文转自https://www.cnblogs.com/fanguangdexiaoyuer/p/7077520.html 感谢作者 可以设置观察的操作:exists,getChildren,getD ...

  7. 【Linux】linux下查看目录所在分区

    命令如下: df -h 目录名 具体使用例子如下:查看/home/sxd/文档处于哪个分区 ------------------------------------------------------ ...

  8. WCF 与其它技术的比较

    以下特性WCF都支持 特性 Web Service .Net Remoting Enterprise Services WSE(WS Enhancements) MSMQ 具有互操作性的Web服务 支 ...

  9. this的四种绑定规则总结

    一.默认绑定 1.全局环境中,this默认绑定到window 2.函数独立调用时,this默认绑定到window console.log(this === window);//true functio ...

  10. 关于ElasticSearch默认窗口结果集参数max_result_window修改

    在Linux服务器中执行如下命令 curl -XPUT http://192.168.46.163:9200/t_order/_settings -d '{ "index" : { ...