在实际工作中充满了 连接池 的使用,如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 实现
连接池原来这么简单(一分钟系列)