Master-worker模式

阅读更多

1、Master-worker模式:

      常用的并行计算模式。

      核心思想为:系统中有两个进程协同工作:Master进程,worker进程。

      Master:负责接收与分配任务,当worker(线程任务)执行完毕后,将返回的结果告知Master,Master对接收的任务进行汇总处理。

      Worker:为一个线程任务对象,处理Master分配的任务,并将任务保存,用于Master后续的处理。

 

2、流程图:


Master-worker模式_第1张图片
 

3、Master,worker实现说明

(1)Master中使用到的容器

  ConcurrentLinkedQueue:用户保存用户提交的任务,该容器通过无锁的方式实现高并发情况下高性能;

  HashMap:Master指定的线程对象放入该容器中,因为由Master初始化时自己决定线程个数,不存在线程安全问题;

   ConcurrentHashMap:存放worker线程任务执行完毕后的结果集,会存在多个线程共享数据问题,因此选择高并发情况下的高性能的容器;

 

(2)Worker:

 ①实现Runnable接口,其实质为一个线程任务对象;

②持有Master中存放任务队列(ConcurrentLinkedQueue)的引用;

③持有Master中,线程执行完毕存放任务数据的Map(ConcurrentHashMap)的引用;

 

4、代码示例

(1)Master类

package net.oschina.tkj.mulitcoding.mastrerworkmodel;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * Master-work模式
 * 
 * 主类的功能:1,接收任务,2,将任务分配给worker 3,当前worker任务执行完成进行结果汇总处理
 * 
 * @author Freedom
 * 
 */
public class Master {

	// 用来存放任务的队列
	// ConcurrentLinkedList 并发时,队列的性能高
	private final ConcurrentLinkedQueue jobQueue = new ConcurrentLinkedQueue<>();

	// 存放worker的map
	// 此处,选择HashMap是因为wokers的数量是有Master决定,在Master初始化时已经设定好了worker数量,不会产生线程安全问题
	private final Map workers = new HashMap();

	// 存放任务的的map,会存在并发问题 ,因此要使用并发安全的map
	private final ConcurrentHashMap resultMap = new ConcurrentHashMap();

	/**
	 * 初始化Master指定worker
	 * 
	 * @param w
	 *            worker
	 * @param jobCount
	 *            任务数量
	 */
	public Master(Worker w, int jobCount) {
		// worker 设置保存任务的queue引用以及任务执行完成的结果集map引用
		w.setQueue(jobQueue);
		w.setResultMap(resultMap);
		// 分配任务的线程
		for (int i = 1; i <= jobCount; i++) {
			workers.put(String.valueOf(i), new Thread(w));
		}
	}

	// 接受任务,Master中每次来一个任务就保存起来
	public void submit(Task t) {
		jobQueue.add(t);
	}

	// 分配,执行任务
	public void executer() {
		for (Map.Entry map : workers.entrySet()) {
			map.getValue().start();
		}
	}

	// 线程执行完成
	public boolean isComplete() {

		for (Map.Entry map : workers.entrySet()) {
			if (map.getValue().getState() != Thread.State.TERMINATED) {
				return false;
			}
		}

		return true;
	}

	// Master汇总,每个worker线程传来的结果数据
	public int getResutlts() {
		int price = 0;
		for (Map.Entry map : resultMap.entrySet()) {
			price += (int) map.getValue();
		}
		return price;
	}

}

 

(2)worker类

package net.oschina.tkj.mulitcoding.mastrerworkmodel;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 线程任务
 * 
 * 1.持有Master中装任务的ConcurrentLinkedQueue的引用
 * 
 * 2.持有Master中返回结果的ConcurrentHashMap的引用
 * 
 * @author Freedom
 * 
 */
public class Worker implements Runnable {

	private ConcurrentLinkedQueue queue;

	private ConcurrentHashMap resultMap;

	public ConcurrentLinkedQueue getQueue() {
		return queue;
	}

	public void setQueue(ConcurrentLinkedQueue queue) {
		this.queue = queue;
	}

	public ConcurrentHashMap getResultMap() {
		return resultMap;
	}

	public void setResultMap(ConcurrentHashMap resultMap) {
		this.resultMap = resultMap;
	}

	@Override
	public void run() {

		Task t = null;
		Object o = null;
		while (true) {
			if (null == queue.poll()) {
				break;
			}
			t = queue.poll();
			// 处理任务的业务逻辑,很耗时
			o = handler(t);
			// worker处理好的任务放回到结果map中
			resultMap.put(String.valueOf(t.getId()), o);
		}

	}

	/*
	 * worker处理每一个任务的业务逻辑
	 */
	private Object handler(Task t) {

		Object o = t.getPrice();
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return o;
	}

}

(3)数据实体类

package net.oschina.tkj.mulitcoding.mastrerworkmodel;

public class Task {

	private int id;
	private int price;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

}

  

(4)Main类

package net.oschina.tkj.mulitcoding.mastrerworkmodel;

import java.util.Random;

public class Main {

	public static void main(String[] args) {

		Master master = new Master(new Worker(), 100);
		Random r = new Random();
		Task t = null;
		for (int i = 1; i <= 100; i++) {
			t = new Task();
			t.setId(i);
			t.setPrice(r.nextInt(300));
			master.submit(t);
		}

		master.executer();
		long start = System.currentTimeMillis();
		while (true) {
			if (master.isComplete()) {
				long end = System.currentTimeMillis();
				int priceR = master.getResutlts();
				System.out.println("最终执行结果price:" + priceR + " 执行时间:"
						+ (end - start));
				break;
			}
		}
	}

}

 

 

 

 

  • Master-worker模式_第2张图片
  • 大小: 84.1 KB
  • 查看图片附件

你可能感兴趣的:(Master-worker模式)