master-worker模式,我们生活中有很多这样的例子,比如一个小组会有一个组长,组长负责给每个人分配任务,也监控每个人的工作情况。
Worker实现
PlusWorker实现
结果
Master-Worker模式
是常用的并行模式,它的核心思想是,系统由两个重要角色组成,一个为Master,用于任务的分配和最终结果的合成;一个为Worker,用于实际处理一个任务。
Master-Worker模式的好处,它能够将一个大人物分解成若干个小任务,并行执行(体现分治的思想),从而可以提高系统的吞吐量。对于系统用户的请求,任务一旦提交,Master会分配任务并立即返回,并不会等待系统全部处理完成后再返回,它具体的处理时异步的。
master-worker模式是使用多线程进行数据处理的结构,多个worker协作处理用户请求,mater负责维护worker,并负责整合最终结果集。
Master-Worker代码:
Master实现
package com.tgb.masterworker;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicLong;
/**
* Created by zhangsisi on 2017/7/29.
*/
public class Master {
/**
* 任务列表
*/
private Queue<Object> jobQueue = new ConcurrentLinkedQueue<Object>();
/**
* worker组
*/
private Map<String,Thread> workers = new HashMap<>();
/**
* 结果集
*/
private Queue<Object> results = new ConcurrentLinkedQueue<Object>();
/**
* 原始任务数
*/
private AtomicLong oriJobNum = new AtomicLong(0);
public Master(int workerNum, Class<? extends Worker> workerClass)
throws IllegalAccessException, InstantiationException {
for(int i=0;i<workerNum;i++){
Worker worker = workerClass.newInstance();
worker.setJobQueue(jobQueue);
worker.setResults(results);
worker.setId(i);
workers.put(Integer.toString(i),
new Thread(worker,Integer.toString(i)));
}
}
/**
* 任务是否已经完成
* @return
*/
public boolean isComplete(){
for(Map.Entry<String,Thread> worker:workers.entrySet()){
if(Thread.State.TERMINATED!= worker.getValue().getState()){
return false;
}
}
return true;
}
/**
* 由client端提交一个子任务
* @param job
*/
public void submit(Object job){
oriJobNum.incrementAndGet();//允许动态增加任务
jobQueue.add(job);
}
/**
* 返回子任务结果集
*/
public Queue<Object> getResults(){
return results;
}
/**
* 将运行结果放到结果集
* @param result
*/
public void putResult(Object result){
results.add(result);
}
/**
* 启动worker,进行任务处理
*/
public void execute(){
for(Map.Entry<String,Thread> entry:workers.entrySet()){
entry.getValue().start();
}
}
/**
* 获取完成任务占比
* @return
*/
public float getFinishRatio(){
return 100.0f - 100.0f *((float)jobQueue.size()/oriJobNum.get());
}
}
Worker实现
package com.tgb.masterworker;
import java.util.Queue;
/**
* Created by zhangsisi on 2017/7/29.
*/
public abstract class Worker implements Runnable{
private int id;
//任务队列,用于获得子任务
protected Queue<Object> jobs;
//子任务处理结果集
protected Queue<Object> results;
//子任务的处理逻辑,在子类中实现具体逻辑
public abstract Object handle(Object input);
@Override
public void run() {
System.out.println(String.format("Worker:[%d] start working...",this.id));
while (true){
//贪婪式获取任务
Object input = jobs.poll();
if(null == input) break;
//将处理结果写入结果集
putResult(handle(input));
}
System.out.println(String.format("Worker:[%d] finish the jobs...",this.id));
}
public void setId(int id) {
this.id = id;
}
public void setJobQueue(Queue<Object> jobQueue) {
this.jobs = jobQueue;
}
public void setResults(Queue<Object> results) {
this.results = results;
}
private void putResult(Object result){
results.add(result);
}
}
PlusWorker实现
package com.tgb.masterworker;
/**
* Created by zhangsisi on 2017/7/29.
*/
public class PlusWorker extends Worker {
@Override
public Object handle(Object input) {
long i =(Long)input;
return i*i*i;
}
}
Client客户端调用
package com.tgb.masterworker;
import java.util.Queue;
/**
* Created by zhangsisi on 2017/7/29.
*/
public class Client {
private static int jobNum = 100;
public static void main(String[] args) throws InterruptedException {
testMasterWorker();
System.out.println("-----------------");
}
static void testMasterWorker() throws InterruptedException {
Master master = null;
try {
//固定4个Worker
master = new Master(4,PlusWorker.class);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
//提交100个子任务
for(long i = 1;i<=jobNum;i++){
master.submit(i);
}
//开始计算
master.execute();
long re =0;
while (true){
//等待计算结束
if(master.isComplete()){
Queue<Object> results = master.getResults();
for(Object result:results){
re = re + (long)result;
}
System.out.println(master.getFinishRatio()+"%");
break;
}
else{
System.out.println(master.getFinishRatio()+"%");
Thread.sleep(1);
}
}
System.out.println(re);
}
}
结果
总结:
master-worker模式是一种将串行任务并行化的方法,被分解的子任务在系统中可被并行处理。采用的是分治的思想,将大任务分解为小的任务,启用多个线程进行并行处理,提高系统的吞吐量。