在实际工作中充满了 连接池 的使用,如JDBC连接池、JDBC连接池、jedis中连接池、http连接池以及tcp连接池等等,几乎需要使用连接的地方都会出现连接池。
每次连接都需要经历建立连接(connect)->通信->关闭连接(Close),连接过程中的connect和close比较消耗系统资源。互联网绝大部分应用都是高IO的,在并发量较高时,频繁的connect和close将会成为系统的瓶颈。
连接池一般是在系统启动时初始化一批连接,当需要通行时,将从建立好的连接中找出空闲的连接用于通信,使用完毕之后再将连接放回连接池中,这样就避免了反复connect和close,提升性能。
/** * 初始化连接池 * @param min 连接池最小个数 * @param max 连接池最大个数 * @param connectFactory 连接对象工厂 */ private void initPool(int min,int max,ConnectFactory<Pooled<T>> connectFactory){ for(int idx = 0;idx<min;idx++){ conList.add(connectFactory.newInstance()); } this.min = min; this.max = max; this.connectFactory = connectFactory; }
/** * 租用连接池 * @return */ public synchronized T lease(){ for(Pooled<T> conn:conList){ if(!conn.isUsed()){ return conn.getPooledObj(); } } expanse(1); return lease(); } /** * 扩展连接池大小 * @param extra */ private synchronized void expanse(int extra){ if(conList.size()+extra>max){ throw new IllegalArgumentException("extra is too far"); } for(int idx=0;idx<extra;idx++){ conList.add(connectFactory.newInstance()); } }
public synchronized void giveBack(T con){ for(Pooled<T> ele:conList){ if(ele.getPooledObj()==con){ ele.free(); } } }
上面代码只是一个demo,在生产环境使用还有许多问题需要解决:
HttpClient 连接池
Apache Commons Pool 对象池实现
c3po 实现
连接池原来这么简单(一分钟系列)