master-worker模式
master需要一个队列存放任务、一个hashMap存放worker对象,这个对象不存在并发,一个结果集存放结果,因为很多个worker在同时操作这个结果集,所以选择使用concurrentHashMap;同样的每一个worker都需要这个队列和结果集。
Master-Worker模式是常用的并行模式之一,它的核心思想是,系统有两个进程协作工作:Master进程,负责接收和分配任务;Worker进程,负责处理子任务。当Worker进程将子任务处理完成后,结果返回给Master进程,由Master进程做归纳汇总,最后得到最终的结果。
什么是Master-Worker模式:
该模式的结构图:
结构图:
Worker:用于实际处理一个任务;
Master:任务的分配和最终结果的合成;
Main:启动程序,调度开启Master。
1、Master代码:
package master_worker;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
public class Master {
// 1、承装任务的集合
private ConcurrentLinkedQueue<Task> workQuene = new ConcurrentLinkedQueue<>();
// 2.使用hashMap装所有的worker对象;
private HashMap<String, Thread> workers = new HashMap<>();
// 3、使用一个容器承装每一个worker并发执行结果
private ConcurrentHashMap<String, Object> resultMap = new ConcurrentHashMap<>();
// 4、构造方法
public Master(Worker worker, int workerCount) {
// 每一個worker都需要有Master的引用用於任務的領取
worker.setWorkQuene(this.workQuene);
worker.setResultMap(this.resultMap);// 用於任務的提交
for (int i = 0; i <= workerCount; i++) {
// key每一个worker的名字,value线程执行对象
workers.put("子节点" + Integer.toString(i), new Thread(worker));
}
}
// 5、提交任务
public void submit(Task task) {
this.workQuene.add(task);
}
// 6、需要一个执行的方法(启动应用程序,让所有的worker工作)
public void execute() {
for (Map.Entry<String, Thread> me : workers.entrySet()) {
me.getValue().start();
}
}
//8、判断线程是否执行完毕
public boolean isComplete() {
for (Map.Entry<String, Thread> me : workers.entrySet()) {
if(me.getValue().getState() != Thread.State.TERMINATED){
return false;
}
}
return true;
}
//返回结果集数据
public int getResult() {
int ret = 0;
for(Map.Entry<String, Object> me:resultMap.entrySet()){
//汇总的逻辑
ret+=(Integer)me.getValue();
}
return ret;
}
}
2、worker代码:
package master_worker;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
public abstract class Worker implements Runnable{
ConcurrentHashMap<String, Object> resultMap;
ConcurrentLinkedQueue<Task> workQuene;
public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
this.resultMap=resultMap;
}
public void setWorkQuene(ConcurrentLinkedQueue<Task> workQuene) {
this.workQuene=workQuene;
}
@Override
public void run() {
while(true){
Task input = this.workQuene.poll();
if(input == null) {
break;
}
//以下是正真的业务处理
Object outPut = handle(input);
this.resultMap.put(Integer.toString(input.getId()), outPut);
}
}
//具体处理任务的代码写在子类中
public abstract Object handle(Task input);
/*//业务逻辑
private Object handle(Task input) {
Object outPut=null;
try {
//表示任务的耗时,可能是数据加工或者操作数据库
Thread.sleep(500);
outPut = input.getPrice();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return outPut;
}*/
}
3、Main代码:
package master_worker;
import java.util.Random;
public class Main {
public static void main(String[] args) {
Master master = new Master(new MyWork(), Runtime.getRuntime().availableProcessors());//Runtime.getRuntime().availableProcessors()当前机器可用的线程数
Random r = new Random();
for(int i=1;i<=100;i++){//100个任务
Task t=new Task();
t.setId(i);
t.setName("任务"+i);
t.setPrice(r.nextInt(1000));
master.submit(t);
}
master.execute();
long start = System.currentTimeMillis();
while(true){
if(master.isComplete()){
long end = System.currentTimeMillis()-start;
int ret = master.getResult();
System.out.println("最终结果:"+ret+",执行耗时:"+end);
break;
}
}
}
}
4、Task代码:
package master_worker;
public class Task {
private int id;
private String name;
private int price;
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 getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
5、MyWorker代码:
package master_worker;
public class MyWork extends Worker{
@Override
public Object handle(Task input) {
Object outPut=null;
try {
//表示任务的耗时,可能是数据加工或者操作数据库
Thread.sleep(500);
outPut = input.getPrice();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return outPut;
}
}
将Worker抽象出来,具体的业务逻辑写在子类中,可以扩张业务。

浙公网安备 33010602011771号