/**
 * 
 */
package cque;

/**
 * @author Xiong
 * 并发节点池（多生产者，多消费者），使用线程局部存储来实现多消费者（get）
 */
public class ConcurrentNodePool {
	private ThreadLocal<MpscNodePool> local = new ThreadLocal<MpscNodePool>();
	private INodeFactory nodeFactory;
	private final int initSize;
	private final int maxSize;
	
	/**
	 * 创建默认的节点池
	 * @param nodeFactory 不可为null
	 */
	public ConcurrentNodePool(INodeFactory nodeFactory){
		this(nodeFactory, 0, Integer.MAX_VALUE);
	}
	
	/**
	 * 根据指定大小参数创建节点池
	 * @param nodeFactory 不可为null
	 * @param initSize
	 * @param maxSize
	 */
	public ConcurrentNodePool(INodeFactory nodeFactory, int initSize, int maxSize){
		assert nodeFactory != null;
		this.nodeFactory = nodeFactory;
		this.initSize = initSize;
		this.maxSize = maxSize;
	}
	
	/**
	 * 取得当前线程的节点池
	 * @return 节点池
	 */
	public MpscNodePool getLocalPool(){
		MpscNodePool pool = local.get();
		if (pool == null){
			INode[] ns = new INode[initSize];
			for (int i=0; i<initSize; ++i){
				ns[i] = nodeFactory.createInstance();
			}
			pool = new MpscNodePool(ns, maxSize);
			local.set(pool);
		}
		return pool;
	}

	/**
	 * 从池中获取一个可用的节点
	 * @return
	 */
	public <T> T get(){
		MpscNodePool pool = getLocalPool();
		return get(pool);
	}

	/**
	 * 使用由用户之前保存的节点池来get节点
	 * @param pool 用户之前要在当前线程调用getLocalPool来获取当前线程的节点池
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T get(MpscNodePool pool){
		assert pool == getLocalPool();
		INode n = pool.get();
		if (n == null){
			n = nodeFactory.createInstance();
			n.onGet(pool);
		}
		return (T) n;
	}
}

@@ -248,30 +248,24 @@
 ;%0D%0A%09private 
-final 
 int initSize
@@ -280,14 +280,8 @@
 ate 
-final 
 int 
@@ -774,24 +774,239 @@
 %7D%0D%0A%09%0D%0A%09/**%0D%0A
+%09 * @param initSize%0D%0A%09 */%0D%0A%09public void setInitSize(int initSize)%7B%0D%0A%09%09this.initSize = initSize;%0D%0A%09%7D%0D%0A%09%0D%0A%09/**%0D%0A%09 * @param maxSize%0D%0A%09 */%0D%0A%09public void setMaxSize(int maxSize)%7B%0D%0A%09%09this.maxSize = maxSize;%0D%0A%09%7D%0D%0A%09%0D%0A%09/**%0D%0A
 %09 * %E5%8F%96%E5%BE%97%E5%BD%93%E5%89%8D%E7%BA%BF%E7%A8%8B%E7%9A%84%E8%8A%82

add setInitSize and setMaxSize