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抽象出來,具體的業務邏輯寫在子類中,可以擴張業務。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章