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抽象出来,具体的业务逻辑写在子类中,可以扩张业务。

posted @ 2018-02-26 12:38  MysticalYcc  阅读(17)  评论(0)    收藏  举报