在实际中工作,我们经常遇到需要连接池的地方,特别是数据库连接池。
我们为什么需要池呢?因为这些资源的创建,都很消耗资源。因此,我们使用一个对象池,里面预先创建了一些资源对象。当我们需要时,从池中取出对象,而不需要时,把对象返回池中。这样就可以提高代码运行的效率。
Apache Commons Pool(http://commons.apache.org/pool/)为我们提供了很方便的接口来实现对象池。我们唯一需要实现的就是如何产生对象,而不用去考虑一堆多线程问题。
2013年,Apache Commons Pool 2.0 发布,这是一个完全重写的对象池的实现,显著的提升了性能和可伸缩性,特别是在高并发加载的情况下。2.0 版本包含可靠的实例跟踪和池监控,要求 JDK 1.6 或者更新版本。这个版本完全不兼容1.x版本;
Apache Commons Pool从个人的角度来说,有三个关键点
1.Factory
回调。用于对象创建,销毁,验证,防止堵塞等。
2.Pool的配置
池的参数。比如最大多少个,最小多少个,最长堵塞时间等。
3.Pool实例
实际干活的。
ApacheCommons Pool 1.x示例代码:
packagetest.ffm83.commons.pool;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importorg.apache.commons.pool.BasePoolableObjectFactory;
importorg.apache.commons.pool.impl.GenericObjectPool;
/**
*commons pool的简单实用,基于1.x版本
* 1.Factory TestPoolableObjectFactory
* 2.Pool的配置 就是pool
* 3.Pool实例 Resource
* @author范芳铭
*/
public
class PoolBaseUsage {
public
static void main(String[] args) {
final
GenericObjectPool pool = new GenericObjectPool(
new TestPoolableObjectFactory());
pool.setMaxActive(2);
for (int i = 0; i < 6; i++) {
new Thread(new Runnable() {
@Override
public
voidrun() {
try {
Objectobj = pool.borrowObject();//
获取
System.out.println(obj);
Thread.sleep(5000);
pool.returnObject(obj);//归还了
}catch (Exception e){
e.printStackTrace();
}
}
}).start();
}
}
static
classTestPoolableObjectFactory extends
BasePoolableObjectFactory{
public Object makeObject()
throws Exception {
return
newResource();
}
}
static
classResource {
public
static int id;
private
int rid;
public Resource() {
synchronized (this) {
rid = id++;
}
}
public
intgetRid() {
return
rid;
}
@Override
public String toString() {
SimpleDateFormatdf = newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
Stringstr = df.format(newDate()) +
","+ "id:" +
rid;
return str;
}
}
}
结果一些说明,在这里设置了最大线程数为2,启用6个线程去运行:
运行结果:
2014-12-19 14:41:43,id:1
2014-12-19 14:41:43,id:0
2014-12-19 14:41:48,id:0
2014-12-19 14:41:48,id:1
2014-12-19 14:41:53,id:1
2014-12-19 14:41:53,id:0
仔细看这个运行结果,能看到明显分成了3波在运行。
如果我们调整下最大线程数,那么结果应该有明显变化。
将最大线程数调整为 pool.setMaxActive(4);
运行结果如下:
2014-12-19 15:08:39,id:3
2014-12-19 15:08:39,id:1
2014-12-19 15:08:39,id:2
2014-12-19 15:08:39,id:0
2014-12-19 15:08:44,id:3
2014-12-19 15:08:44,id:1
能够明显看到4个线程一起执行,另外两个后续执行;