这样的模型是最经常使用的并行模式之中的一个,在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的网络编程[3] -> BOOTP 协议[0] -> BOOTP 的基本理论

    BOOTP协议 / BOOTP Protocol 目录 基本理论 BOOTP 与 DHCP 通信流程 数据报文格式 报文加解码实现 1. 基本理论 / Basic Theory BOOTP(Boots ...

  2. POJ 3080-Blue Jeans【kmp,字符串剪接】

    Blue Jeans Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20695   Accepted: 9167 Descr ...

  3. poj2104(划分树模板)

    poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...

  4. First Missing Positive -- LeetCode

    Given an unsorted integer array, find the first missing positive integer. For example,Given [1,2,0]  ...

  5. PHP switch的“高级”用法详解

    只所以称为“高级”用法,是因为我连switch的最基础的用法都还没有掌握,so,接下来讲的其实还是它的基础用法! switch 语句和具有同样表达式的一系列的 IF 语句相似.很多场合下需要把同一个变 ...

  6. SQL常用函数之五 str()

    原文:SQL常用函数之五 str() 使用str函数   :STR 函数由数字数据转换来的字符数据.   语法      STR    (    float_expression    [    ,  ...

  7. UBIFS - UBI File-System

    参考:http://www.linux-mtd.infradead.org/doc/ubifs.html#L_raw_vs_ftl UBIFS - UBI File-System Table of c ...

  8. 能上架App的GooglePlay开发者账号获取流程

    googleplay 开发者账号申请流程 接到公司号召,要让我们的app走向世界,上架GooglePlay,都说天朝的Android 程序员是折翼的天使,猛然发现写了做么多年的Android,竟然不知 ...

  9. 1019(C++)

    计算n个数的最小公倍数,可用欧几里得算法计算两个数字的最大公约数,再计算两个数最小公倍数 有了2个数最小公倍数算法就简单了,即为:计算第一和第二个数得到最小公倍数lc,再计算lc和第三个数最小公倍数. ...

  10. 详细理解javascript中的强制类型转换

    将值从一种类型转换为另一种类型通常称为类型转换,这是显式的情况:隐式的情况称为强制类型转换,JavaScript 中的强制类型转换总是返回标量基本类型值,如字符串.数字和布尔值. 如何理解: 类型转换 ...