1 概念和核心思想
Master-worker模式是常用的并行设计模式之一。它的核心思想是,系统由两类线程协同工作:Master线程负责接收和分配任务,worker线程负责完成子任务,并且将处理结果返回给master线程。然后master线程做归纳汇总,从而得到最终结果。
Master-worker模式的好处是,它能够将一个大任务分解成多个小任务,分配给多个线程并行执行,从而提高效率。
2 Master-Worker模式的结构
(1)工作示意图:
(2)结构图:
3 涉及到的角色
(1)Worker:扩展Thread类,或者实现runnable接口。用于实际处理一个子任务。
(2)Master:用于任务的分配和最终结果的归纳整理。
(3)client: 启动系统。
Master线程为主要的线程,维护了一个Worker线程列表,子任务队列和一个结果集。Worker线程列表中的线程不断地从任务队列中获取子任务,将处理结果写入结果集,直到任务队列为空。
4 代码实现
(1)Master.java:
public class Master {
/**
* 任务队列
* 由于有多个线程要访问这个队列,因此使用并发队列,保证线程安全
*/
private Queue<Object> jobs=new ConcurrentLinkedQueue<Object>();
/**
* 结果集,存放从多个worker进程中计算得出的结果
* 使用并发的list
*/
private List<Object> results=Collections.synchronizedList(new ArrayList<Object>());
/**
* 存放worker进程,不需要使用并发list
*/
private List<Thread> workers=new ArrayList<Thread>();
public Master(int countWorker) {
// TODO Auto-generated constructor stub
while((countWorker--)>0){
Thread thread=new Thread(new Worker(jobs, results));
workers.add(thread);
}
}
/**
* 在任务队列中添加一个任务
*/
public void submit(Object job) {
jobs.add(job);
}
/**
* 开始执行任务
*/
public void startExecute(){
for (Thread t : workers) {
t.start();
}
}
/**
* 判断所有子任务是否已经完成
*/
public boolean isComplete() {
for(Thread t:workers){
if(t.getState()!=Thread.State.TERMINATED){
return false;
}
}
return true;
}
public List<Object> getResults() {
return results;
}
}
(2)Worker.java
public class Worker implements Runnable{
/**
* 任务队列,从这里面取一个任务
*/
private Queue<Object> jobs;
/**
* 结果集
*/
private List<Object> results;
public Worker(Queue<Object> jobs,List<Object> results) {
// TODO Auto-generated constructor stub
this.jobs=jobs;
this.results=results;
}
@Override
public void run() {
// TODO Auto-generated method stub
/**
* while循环,一直在获取子任务,直到任务队列为空,跳出循环
*/
while (true) {
Object job=jobs.poll();
if(job==null)
break;
/**
* 计算结果,将结果存到结果集里面去
*/
Object result=handleRequest(job);
results.add(result);
}
}
/**
* 处理任务,在这里实现具体逻辑
*/
public Object handleRequest(Object job) {
int input=(Integer) job;
return input*input*input;
}
}
(3)Client.java:
public class Client {
public static void main(String[] args) {
Master master=new Master(5);
/**
* 提交分解好的子任务
*/
for(int i=0;i<10000;i++){
master.submit(i);
}
long start=System.currentTimeMillis();
master.startExecute();
int result=0;
/**
* 不需要等所有子任务处理完,master进程就可以使用已经计算好的子任务结果
*/
List<Object> results=master.getResults();
/**
* 条件设置的很巧妙,当任务完成并且results为空时,说明所有子任务结果都已处理,跳出循环
*/
while (!results.isEmpty()||!master.isComplete()) {
if (!results.isEmpty()) {
result+=(Integer)results.remove(results.size()-1);
}
}
System.out.println("耗时:"+(System.currentTimeMillis()-start)+" ms");
System.out.println("最终结果:"+result);
}
}
5 参考文献
1>.Java程序性能优化.葛一鸣 等编著.