java master work_并发编程之Master-Worker模式

我们知道,单个线程盘算是串行的,只有等上一个义务竣事之后,才气执行下一个义务,以是执行效率是比较低的。

那么,若是用多线程执行义务,就可以在单元时间内执行更多的义务,而Master-Worker就是多线程并行盘算的一种实现方式。

它的头脑是,启动两个历程协同事情:Master和Worker历程。

Master卖力义务的吸收和分配,Worker卖力详细的子义务执行。每个Worker执行完义务之后把效果返回给Master,最后由Master汇总效果。(实在也是一种分而治之的头脑,和forkjoin盘算框架有相似之处,参看:并行义务盘算框架forkjoin)

Master-Worker事情示意图如下:

952fa04706ce680dc8aaccec57a364f8.png

下面用Master-Worker实现盘算1-100的平方和,思绪如下:

界说一个Task类用于存储每个义务的数据。

Master生产牢固个数的Worker,把所有worker存放在workers变量(map)中,Master需要存储所有义务的行列workqueue(ConcurrentLinkedQueue)和所有子义务返回的效果集resultMap(ConcurrentHashMap)。

每个Worker执行自己的子义务,然后把效果存放在resultMap中。

Master汇总resultMap中的数据,然后返回给Client客户端。

为了扩展Worker的功效,用一个MyWorker继续Worker重写义务处置的详细方式。

Task类:

package com.thread.masterworker;

public class Task {

private int id;

private String name;

private int num;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getNum() {

return num;

}

public void setNum(int num) {

this.num = num;

}

}

Master实现:

package com.thread.masterworker;

import java.util.HashMap;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ConcurrentLinkedQueue;

public class Master {

//所有义务的行列

private ConcurrentLinkedQueue workerQueue = new ConcurrentLinkedQueue();

//所有worker

private HashMap workers = new HashMap();

//共享变量,worker返回的效果

private ConcurrentHashMap resultMap = new ConcurrentHashMap();

//组织方式,初始化所有worker

public Master(Worker worker,int workerCount){

worker.setWorkerQueue(this.workerQueue);

worker.setResultMap(this.resultMap);

for (int i = 0; i < workerCount; i++) {

Thread t = new Thread(worker);

this.workers.put("worker-"+i,t);

}

}

//义务的提交

public void submit(Task task){

this.workerQueue.add(task);

}

//执行义务

public int execute(){

for (Map.Entry entry : workers.entrySet()) {

entry.getValue().start();

}

//一直循环,直到效果返回

while (true){

if(isComplete()){

return getResult();

}

}

}

//判断是否所有线程都已经执行完毕

public boolean isComplete(){

for (Map.Entry entry : workers.entrySet()) {

//只要有随便一个线程没有竣事,就返回false

if(entry.getValue().getState() != Thread.State.TERMINATED){

return false;

}

}

return true;

}

//处置效果集返回最终效果

public int getResult(){

int res = 0;

for (Map.Entry entry : resultMap.entrySet()) {

res += (Integer) entry.getValue();

}

return res;

}

}

父类Worker:

package com.thread.masterworker;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ConcurrentLinkedQueue;

public class Worker implements Runnable {

private ConcurrentLinkedQueue workerQueue;

private ConcurrentHashMap resultMap;

public void setWorkerQueue(ConcurrentLinkedQueue workerQueue) {

this.workerQueue = workerQueue;

}

public void setResultMap(ConcurrentHashMap resultMap) {

this.resultMap = resultMap;

}

@Override

public void run() {

while(true){

//从义务行列中取出一个义务

Task task = workerQueue.poll();

if(task == null) break;

//处置详细的义务

Object res = doTask(task);

//把每次处置的效果放到效果集内里,此处直接把num值作为效果

resultMap.put(String.valueOf(task.getId()),res);

}

}

public Object doTask(Task task) {

return null;

}

}

子类MyWorker继续父类Worker,重写doTask方式实现详细的逻辑:

package com.thread.masterworker;

public class MyWorker extends Worker {

@Override

public Object doTask(Task task) {

//暂停0.5秒,模拟义务处置

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

//盘算数字的平方

int num = task.getNum();

return num * num;

}

}

客户端Client:

package com.thread.masterworker;

import java.util.Random;

public class Client {

public static void main(String[] args) {

Master master = new Master(new MyWorker(), 10);

//提交n个义务到义务行列里

for (int i = 0; i < 100; i++) {

Task task = new Task();

task.setId(i);

task.setName("义务"+i);

task.setNum(i+1);

master.submit(task);

}

//执行义务

long start = System.currentTimeMillis();

int res = master.execute();

long time = System.currentTimeMillis() - start;

System.out.println("效果:"+res+",耗时:"+time);

}

}

以上,我们用10个线程去执行子义务,最终由Master做盘算求和(1-100的平方和)。每个线程暂停500ms,盘算数字的平方值。

总共100个义务,分10个线程并行盘算,相当于每个线程均分10个义务,一个义务的时间也许为500ms,故10个义务为5000ms,再加上盘算平方值的时间,故稍大于5000ms。效果如下,

效果:338350,耗时:5084

原文链接:https://www.cnblogs.com/starry-skys/p/12341170.html

本站声明:网站内容来源于网络,若有侵权,请联系我们,我们将及时处置。

UnityTips:不要在发布版本中实现OnGUI方法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值