package jef.common.pool; import java.sql.SQLException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import jef.common.log.LogUtil; import jef.tools.Assert; /** * 默认实现.不支持重入 * * @author jiyi * * @param <T> */ public class SimplePool<T> implements ObjectPool<T>, Releasable { private int max; private int min; private BlockingQueue<T> freeConns; private AtomicInteger used = new AtomicInteger();// 被取走的连接数 protected ObjectFactory<T> factory; /** * 构造 * * @param max * 最大值 * @param min * 最小值 */ public SimplePool(ObjectFactory<T> fac, int min, int max) { if (min > max) min = max; this.min = min; this.max = max; this.factory = fac; Assert.notNull(fac); freeConns = new LinkedBlockingQueue<T>(max); ReleaseThread.getInstance().addPool(this); } public T poll() { try { T conn; if (freeConns.isEmpty() && used.get() < max) {// 尝试用新连接 used.incrementAndGet(); //必须立刻累加计数器,否则并发的线程会立刻抢先创建对象,从而超出连接池限制 conn = factory.create(); } else { conn = freeConns.poll(5000000000L, TimeUnit.NANOSECONDS);// 5秒 if (conn == null) { throw new IllegalStateException("No object avaliable now."); } used.incrementAndGet(); conn = factory.ensureOpen(conn); } return conn; } catch (InterruptedException e) { throw new RuntimeException(e); } } public void offer(T conn) { boolean success = freeConns.offer(conn); used.decrementAndGet(); if (!success) { factory.release(conn);// 塞不下了。肯定是关闭掉 } } /** * 获得对象池状态 * * @return */ public PoolStatus getStatus() { int used = this.used.get(); int free = freeConns.size(); return new PoolStatus(max, min, used + free, used, free); } /** * 收缩对象池 */ public synchronized void releaseTillMinSize() { // System.out.println("开始收缩"+ freeConns.size()+":"+ used.get()); if (freeConns.size() > min) { T conn; while ((conn = freeConns.poll()) != null && freeConns.size() > min) { try { factory.release(conn); } catch (Exception e) { LogUtil.exception(e); } } } // System.out.println("结束收缩"+ freeConns.size()+":"+ used.get()); } /** * 关闭对象池 * * @throws SQLException */ public void closePool() { ReleaseThread.getInstance().removePool(this); max = 0; min = 0; releaseTillMinSize(); } }