分级事件驱动架构SEDA( Staged Event Driven Architecture)的构造类

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.log4j.Logger;

/**
 * <pre>
 * 分级事件驱动架构SEDA( Staged E ventDriven A rch itecture)的构造类
 * @author kanpiaoxue
 * @param <Task> SEDAThreadPoolUtils内置的 interface Task
 * 2013-11-07
 * </pre>
 */
public final class SEDAThreadPool {
	private static final Logger LOGGER = Logger.getLogger(SEDAThreadPool.class);
	private final BlockingQueue<SEDAThreadPool.Task> inputQueue;
	private final BlockingQueue<SEDAThreadPool.Task> outputQueue;
	private final ExecutorService exec;
	private final String threadName;
	private final int threadPoolSize;
	private final ConcurrentHashMap<SEDAThreadPool.Task, SEDAThreadPool.Task> conflictMap;
	private volatile boolean hasOutput;
	private volatile boolean hasConflictMap;

	/**
	 * <pre>
	 * @param threadName 工作线程的名称
	 * @param inputQueue 输入任务的队列
	 * @param outputQueue 输出任务的队列。当不存在输出队列是,该项可以为 null
	 * @param exec 执行的线程池。如果该项为 null,则采用默认的 Executors.newCachedThreadPool()
	 * @param threadPoolSize 线程池的大小
	 * </pre>
	 */
	public SEDAThreadPool(String threadName, BlockingQueue<Task> inputQueue,
			BlockingQueue<Task> outputQueue, ExecutorService exec,
			int threadPoolSize) {
		this(threadName, inputQueue, outputQueue, exec, threadPoolSize, null);
	}

	/**
	 * <pre>
	 * @param threadName 工作线程的名称
	 * @param inputQueue 输入任务的队列
	 * @param exec 执行的线程池。如果该项为 null,则采用默认的 Executors.newCachedThreadPool()
	 * @param threadPoolSize 线程池的大小
	 * </pre>
	 */
	public SEDAThreadPool(String threadName, BlockingQueue<Task> inputQueue,
			ExecutorService exec, int threadPoolSize) {
		this(threadName, inputQueue, null, exec, threadPoolSize, null);
	}

	/**
	 * <pre>
	 * @param threadName 工作线程的名称
	 * @param inputQueue 输入任务的队列
	 * @param exec 执行的线程池。如果该项为 null,则采用默认的 Executors.newCachedThreadPool()
	 * @param threadPoolSize 线程池的大小
	 * @param conflictMap Task发生冲突Map :和 conflictMap 中的key存在冲突的任务都不会被执行
	 * </pre>
	 */
	public SEDAThreadPool(
			String threadName,
			BlockingQueue<Task> inputQueue,
			ExecutorService exec,
			int threadPoolSize,
			ConcurrentHashMap<SEDAThreadPool.Task, SEDAThreadPool.Task> conflictMap) {
		this(threadName, inputQueue, null, exec, threadPoolSize, conflictMap);
	}

	/**
	 * <pre>
	 * @param threadName 工作线程的名称
	 * @param inputQueue 输入任务的队列
	 * @param outputQueue 输出任务的队列。当不存在输出队列是,该项可以为 null
	 * @param exec 执行的线程池。如果该项为 null,则采用默认的 Executors.newCachedThreadPool()
	 * @param threadPoolSize 线程池的大小
	 * @param conflictMap Task发生冲突Map :和 conflictMap 中的key存在冲突的任务都不会被执行
	 * </pre>
	 */
	public SEDAThreadPool(
			String threadName,
			BlockingQueue<SEDAThreadPool.Task> inputQueue,
			BlockingQueue<SEDAThreadPool.Task> outputQueue,
			ExecutorService exec,
			int threadPoolSize,
			ConcurrentHashMap<SEDAThreadPool.Task, SEDAThreadPool.Task> conflictMap) {
		super();
		this.threadName = threadName;
		this.inputQueue = inputQueue;
		this.outputQueue = outputQueue;
		this.exec = (null == exec) ? Executors.newCachedThreadPool() : exec;
		this.threadPoolSize = threadPoolSize;
		this.conflictMap = conflictMap;
		if (null != conflictMap) {
			hasConflictMap = true;
		}
		this.hasOutput = (null != outputQueue);

	}

	/**
	 * <pre>
	 * 创建SEDA线程池
	 * </pre>
	 */
	public void createSEDAThreadPool() {
		for (int i = 0; i < threadPoolSize; i++) {
			exec.execute(new InnerConsumer(threadName + i, inputQueue,
					outputQueue));
		}
	}

	private class InnerConsumer implements Runnable {
		private final String name;
		private final BlockingQueue<SEDAThreadPool.Task> inputQueue;
		private final BlockingQueue<SEDAThreadPool.Task> outputQueue;

		public InnerConsumer(String name,
				BlockingQueue<SEDAThreadPool.Task> inputQueue,
				BlockingQueue<SEDAThreadPool.Task> outputQueue) {
			super();
			this.name = name;
			this.inputQueue = inputQueue;
			this.outputQueue = outputQueue;
		}

		@Override
		public void run() {
			Thread.currentThread().setName(name);
			if (LOGGER.isInfoEnabled()) {
				LOGGER.info(name + " start to work.");
			}
			while (true) {
				try {
					SEDAThreadPool.Task inputTask = inputQueue.take();
					try {
						if (hasConflictMap) {
							if (null != conflictMap.putIfAbsent(inputTask,
									inputTask)) {
								if (LOGGER.isDebugEnabled()) {
									LOGGER.debug(inputTask
											+ " has found in conflictMap, it is abandoned.");
								}
								continue;
							} else {
								if (LOGGER.isDebugEnabled()) {
									LOGGER.debug(inputTask
											+ " is put into conflictMap.");
								}
							}
						}
						SEDAThreadPool.Task outputTask = consume(inputTask);
						if (hasOutput && null != outputTask) {
							outputQueue.put(outputTask);
							if (LOGGER.isDebugEnabled()) {
								LOGGER.debug(outputTask
										+ " put into outputQueue.");
							}
						}
					} finally {
						if (hasConflictMap
								&& null != conflictMap.remove(inputTask)) {
							if (LOGGER.isDebugEnabled()) {
								LOGGER.debug(inputTask
										+ " is removed from conflictMap.");
							}
						}
					}
				} catch (Exception e) {
					LOGGER.error("Error:" + e.getMessage(), e);
				}
			}
		}

		private SEDAThreadPool.Task consume(SEDAThreadPool.Task task) {
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug(task + " takes from inputQueue.");
			}
			return task.execute() ? task : null;
		}
	}

	/**
	 * <pre>
	 * SEDA的Task接口
	 * @author kanpiaoxue
	 * </pre>
	 * 
	 */
	public interface Task {
		public boolean execute();
	}

}

 

 

 

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import com.wanmei.parallel.seda.SEDAThreadPool.Task;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		BlockingQueue<SEDAThreadPool.Task> inputQueue = new LinkedBlockingQueue<SEDAThreadPool.Task>();
		BlockingQueue<SEDAThreadPool.Task> inputQueue2 = new LinkedBlockingQueue<SEDAThreadPool.Task>();
		BlockingQueue<SEDAThreadPool.Task> inputQueue3 = new LinkedBlockingQueue<SEDAThreadPool.Task>();

		ConcurrentHashMap<SEDAThreadPool.Task, SEDAThreadPool.Task> conflictMap = test();
		int threadPoolSize = Runtime.getRuntime().availableProcessors() * 4;

		ExecutorService exec = Executors.newCachedThreadPool();

		SEDAThreadPool pool = new SEDAThreadPool("consumer-1-", inputQueue,
				inputQueue2, exec, threadPoolSize, conflictMap);
		pool.createSEDAThreadPool();

		SEDAThreadPool pool2 = new SEDAThreadPool("consumer-2-", inputQueue2,
				inputQueue3, exec, threadPoolSize, conflictMap);
		pool2.createSEDAThreadPool();

		SEDAThreadPool pool3 = new SEDAThreadPool("consumer-3-", inputQueue3,
				exec, threadPoolSize, conflictMap);
		pool3.createSEDAThreadPool();

		exec.execute(new Test().new Producer("producer", inputQueue));

		exec.shutdown();

	}

	private static ConcurrentHashMap<SEDAThreadPool.Task, SEDAThreadPool.Task> test() {
		ConcurrentHashMap<SEDAThreadPool.Task, SEDAThreadPool.Task> conflictMap = new ConcurrentHashMap<SEDAThreadPool.Task, SEDAThreadPool.Task>();
		for (int i = 0; i < 10; i++) {
			Test.TaskImpl t = new Test().new TaskImpl("task-" + i);
			conflictMap.put(t, t);
		}
		return conflictMap;
	}

	private class Producer implements Runnable {
		private final String name;
		private final BlockingQueue<SEDAThreadPool.Task> outputQueue;

		public Producer(String name, BlockingQueue<Task> outputQueue) {
			super();
			this.name = name;
			this.outputQueue = outputQueue;
		}

		@Override
		public void run() {
			Thread.currentThread().setName(name);
			while (true) {
				try {
					for (SEDAThreadPool.Task t : getTasks()) {
						outputQueue.put(t);
					}
					TimeUnit.SECONDS.sleep(10);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		private List<SEDAThreadPool.Task> getTasks() {
			List<SEDAThreadPool.Task> list = new ArrayList<SEDAThreadPool.Task>();
			for (int i = 0; i < 10; i++) {
				list.add(new Test().new TaskImpl("task-" + i));
			}
			return list;
		}
	}

	private class TaskImpl implements SEDAThreadPool.Task {
		private String name;

		public TaskImpl(String name) {
			super();
			this.name = name;
		}

		@Override
		public int hashCode() {
			final int prime = 37;
			int result = 17;
			result = prime * result + getOuterType().hashCode();
			result = prime * result + ((name == null) ? 0 : name.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			TaskImpl other = (TaskImpl) obj;
			if (!getOuterType().equals(other.getOuterType()))
				return false;
			if (name == null) {
				if (other.name != null)
					return false;
			} else if (!name.equals(other.name))
				return false;
			return true;
		}

		@Override
		public String toString() {
			return "Task [name=" + name + "]";
		}

		@Override
		public boolean execute() {
			try {

				TimeUnit.SECONDS.sleep(10);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return true;
		}

		private Test getOuterType() {
			return Test.this;
		}

	}
}

 

参考: http://www.eecs.harvard.edu/~mdw/proj/seda/

 

你可能感兴趣的:(Architecture)