- 浏览: 58272 次
- 性别:
- 来自: 上海
-
文章分类
最新评论
-
blackartanan:
现在还在更新吗
JDF代码学习 JDF入门教程 代码配置 -
keyboardsun:
keyboardsun 发表于2009年7月10日 9:29: ...
玩转 quartz quartz 教程 quartz 实现 quartz 封装
Jakarta Commons Pool 对象池 使用,测试
本文作者 keyboardsunmail:keyboardsun@163.com
http://www.chinacsharp.net如需转载请标明 出处,作者 等信息
周末两天看了Jakarta Commons Pool的源代码,以及看了网上相关的文章,决定写一篇blog。
以下理论部分摘录自孙海涛 (alexhsun@hotmail.com),的文章。
http://www.ibm.com/developerworks/cn/java/l-common-pool/index.html
恰当地使用对象池化技术,可以有效地减少对象生成和初始化时的消耗,提高系统的运行效率。Jakarta Commons Pool组件提供了一整套用于实现对象池化的框架,以及若干种各具特色的对象池实现,可以有效地减少处理对象池化时的工作量,为其它重要的工作留下更多的精力和时间。
创建新的对象并初始化的操作,可能会消耗很多的时间。在这种对象的初始化工作包含了一些费时的操作(例如,从一台位于20,000千米以外的主机上读出一些数据)的时候,尤其是这样。在需要大量生成这样的对象的时候,就可能会对性能造成一些不可忽略的影响。要缓解这个问题,除了选用更好的硬件和更棒的虚拟机以外,适当地采用一些能够减少
对象创建次数的编码技巧,也是一种有效的对策。对象池化技术(Object Pooling)就是这方面的著名技巧,而JakartaCommons Pool组件则是处理对象池化的得力外援。
对象池化技术
对象池化的基本思路是:将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用,从而在一定程度上减少频繁创建对象所造成的开销。用于充当保存对象的“容器”的对象,被称为“对象池”(Object Pool,或简称Pool)。
PoolableObjectFactory、ObjectPool和ObjectPoolFactory
在Pool组件中,对象池化的工作被划分给了三类对象:
PoolableObjectFactory用于管理被池化的对象的产生、激活、挂起、校验和销毁;
ObjectPool用于管理要被池化的对象的借出和归还,并通知PoolableObjectFactory完成相应的工作;
ObjectPoolFactory则用于大量生成相同类型和设置的ObjectPool。
相应地,使用Pool组件的过程,也大体可以划分成“创立PoolableObjectFactory”、“使用ObjectPool”和可选的“利用ObjectPoolFactory”三种动作。
可口可乐公司的软饮料有可口可乐、雪碧和芬达等品种,百事可乐公司的软饮料有百事可乐、七喜和美年达等类型,而Pool组件提供的ObjectPool实现则有StackObjectPool、SoftReferenceObjectPool和GenericObjectPool等种类。不同类型的软饮料各有各自的特点,分别适应不同消费者的口味;而不同类型的ObjectPool也各有各自的特色,分别适应不同的情况。
StackObjectPool
StackObjectPool利用一个java.util.Stack对象来保存对象池里的对象。这种对象池的特色是: 可以为对象池指定一个初始的参考大小(当空间不够时会自动增长)。 在对象池已空的时候,调用它的borrowObject方法,会自动返回新创建的实例。可以为对象池指定一个可保存的对象数目的上限。达到这个上限之后,再向池里送回的对象会被自动送去回收。
StackObjectPool的构造方法共有六个,其中:
最简单的一个是StackObjectPool(),一切采用默认的设置,也不指明要用的PoolableObjectFactory实例。
最复杂的一个则是StackObjectPool(PoolableObjectFactory factory, int max, int init)。其中:
参数factory指明要与之配合使用的PoolableObjectFactory实例;
参数max设定可保存对象数目的上限;
参数init则指明初始的参考大小。
剩余的四个构造方法则是最复杂的构造方法在某方面的简化版本,可以根据需要选用。它们是:
StackObjectPool(int max)
StackObjectPool(int max, int init)
StackObjectPool(PoolableObjectFactory factory)
StackObjectPool(PoolableObjectFactory factory, int max)
用不带factory参数的构造方法构造的StackObjectPool实例,必须要在用它的setFactory(PoolableObjectFactory factory)方法与某一PoolableObjectFactory实例关联起来后才能正常使用。
这种对象池可以在没有Jakarta Commmons Collections组件支持的情况下正常运行。
SoftReferenceObjectPool利用一个java.util.ArrayList对象来保存对象池里的对象。不过它并不在对象池里直接保存对象本身,而是保存它们的“软引用”(Soft Reference)。这种对象池的特色是:
可以保存任意多个对象,不会有容量已满的情况发生。
在对象池已空的时候,调用它的borrowObject方法,会自动返回新创建的实例。
可以在初始化同时,在池内预先创建一定量的对象。
当内存不足的时候,池中的对象可以被Java虚拟机回收。
SoftReferenceObjectPool的构造方法共有三个,其中:
最简单的是SoftReferenceObjectPool(),不预先在池内创建对象,也不指明要用的PoolableObjectFactory实例。
最复杂的一个则是SoftReferenceObjectPool(PoolableObjectFactory factory, int initSize)。其中:
参数factory指明要与之配合使用的PoolableObjectFactory实例
参数initSize则指明初始化时在池中创建多少个对象。
剩下的一个构造方法,则是最复杂的构造方法在某方面的简化版本,适合在大多数情况下使用。它是:
SoftReferenceObjectPool(PoolableObjectFactory factory)
用不带factory参数的构造方法构造的SoftReferenceObjectPool实例,也要在用它的setFactory(PoolableObjectFactory factory)方法与某一PoolableObjectFactory实例关联起来后才能正常使用。
这种对象池也可以在没有Jakarta Commmons Collections组件支持的情况下正常运行。 GenericObjectPool
GenericObjectPool利用一个org.apache.commons.collections.CursorableLinkedList对象来保存对象池里的对象。这种对象池的特色是:
可以设定最多能从池中借出多少个对象。
可以设定池中最多能保存多少个对象。
可以设定在池中已无对象可借的情况下,调用它的borrowObject方法时的行为,是等待、创建新的实例还是抛出异常。
可以分别设定对象借出和还回时,是否进行有效性检查。
可以设定是否使用一个单独的线程,对池内对象进行后台清理。
GenericObjectPool的构造方法共有七个,其中:
最简单的一个是GenericObjectPool(PoolableObjectFactory factory)。仅仅指明要用的PoolableObjectFactory实例,其它参数则采用默认值。
最复杂的一个是GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle)。其中:
参数factory指明要与之配合使用的PoolableObjectFactory实例。
参数maxActive指明能从池中借出的对象的最大数目。如果这个值不是正数,表示没有限制。
参数whenExhaustedAction指定在池中借出对象的数目已达极限的情况下,调用它的borrowObject方法时的行为。可以选用的值有:
GenericObjectPool.WHEN_EXHAUSTED_BLOCK,表示等待;
GenericObjectPool.WHEN_EXHAUSTED_GROW,表示创建新的实例(不过这就使maxActive参数失去了意义);
GenericObjectPool.WHEN_EXHAUSTED_FAIL,表示抛出一个java.util.NoSuchElementException异常。
参数maxWait指明若在对象池空时调用borrowObject方法的行为被设定成等待,最多等待多少毫秒。如果等待时间超过了这个数值,则会抛出一个java.util.NoSuchElementException异常。如果这个值不是正数,表示无限期等待。
参数testOnBorrow设定在借出对象时是否进行有效性检查。
参数testOnBorrow设定在还回对象时是否进行有效性检查。
参数timeBetweenEvictionRunsMillis,设定间隔每过多少毫秒进行一次后台对象清理的行动。如果这个值不是正数,则实际上不会进行后台对象清理。
参数numTestsPerEvictionRun,设定在进行后台对象清理时,每次检查几个对象。如果这个值不是正数,则每次检查的对象数是检查时池内对象的总数乘以这个值的负倒数再向上取整的结果――也就是说,如果这个值是-2(-3、-4、-5……)的话,那么每次大约检查当时池内对象总数的1/2(1/3、1/4、1/5……)左右。
参数minEvictableIdleTimeMillis,设定在进行后台对象清理时,视休眠时间超过了多少毫秒的对象为过期。过期的对象将被回收。如果这个值不是正数,那么对休眠时间没有特别的约束。
参数testWhileIdle,则设定在进行后台对象清理时,是否还对没有过期的池内对象进行有效性检查。不能通过有效性检查的对象也将被回收。
另一个比较特别的构造方法是GenericObjectPool(PoolableObjectFactory factory, GenericObjectPool.Config config) 。其中:
参数factory指明要与之配合使用的PoolableObjectFactory实例;
参数config则指明一个包括了各个参数的预设值的对象(详见《GenericObjectPool.Config》一节)。
剩下的五个构造函数则是最复杂的构造方法在某方面的简化版本,可以根据情况选用。它们是:
GenericObjectPool(PoolableObjectFactory factory, int maxActive)
GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait)
GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, boolean testOnBorrow, boolean testOnReturn)
GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle)
GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn)
这种对象池不可以在没有Jakarta Commmons Collections组件支持的情况下运行。 GenericObjectPool.Config
调用一个有很多的参数的方法的时候,很可能将参数的位置和个数搞错,导致编译或运行时的错误;阅读包含了有很多参数的方法调用的代码的时候,也很可能因为没有搞对参数的位置和个数,产生错误的理解。因此,人们往往避免给一个方法安排太多的参数的做法(所谓的“Long Parameter List”)。不过,有些方法又确实需要许多参数才能完成工作。于是,就有人想到了一种将大批的参数封装到一个对象(称为参数对象,Parameter Object)里,然后将这个对象作为单一的参数传递的两全其美的对策。
因为生成GenericKeyedObjectPool时可供设置的特性非常之多,所以它的构造方法里也就难免会需要不少的参数。GenericKeyedObjectPool除了提供了几个超长的构造方法之外,同时也定义了一个使用参数对象的构造方法。所用参数对象的类型是GenericKeyedObjectPool.Config。
GenericKeyedObjectPool.Config定义了许多的public字段,每个对应一种可以为GenericKeyedObjectPool设置的特性,包括:
int maxActive
int maxIdle
long maxWait
long minEvictableIdleTimeMillis
int numTestsPerEvictionRun
boolean testOnBorrow
boolean testOnReturn
boolean testWhileIdle
long timeBetweenEvictionRunsMillis
byte whenExhaustedAction
这些字段的作用,与在GenericKeyedObjectPool最复杂的构造方法中与它们同名的参数完全相同。
使用的时候,先生成一个GenericKeyedObjectPool.Config对象,然后将个字段设置为想要的值,最后用这个对象作为唯一的参数调用GenericKeyedObjectPool的构造方法即可。
注意:使用有许多public字段、却没有任何方法的类,也是一个人们往往加以避免的行为(所谓的“Data Class”)。不过这次GenericKeyedObjectPool特立独行了一回。
有时候,单用对池内所有对象一视同仁的对象池,并不能解决的问题。例如,对于一组某些参数设置不同的同类对象――比如一堆指向不同地址的java.net.URL对象或者一批代表不同语句的java.sql.PreparedStatement对象,用这样的方法池化,就有可能取出不合用的对象的麻烦。
可以通过为每一组参数相同的同类对象建立一个单独的对象池来解决这个问题。但是,如果使用普通的ObjectPool来实施这个计策的话,因为普通的PoolableObjectFactory只能生产出大批设置完全一致的对象,就需要为每一组参数相同的对象编写一个单独的PoolableObjectFactory,工作量相当可观。这种时候就适合调遣Pool组件中提供的一种“带键值的对象池”来展开工作了。
Pool组件采用实现了KeyedObjectPool接口的类,来充当带键值的对象池。相应的,这种对象池需要配合实现了KeyedPoolableObjectFactory接口的类和实现了KeyedObjectPoolFactory接口的类来使用(这三个接口都在org.apache.commons.pool包中定义):
KeyedPoolableObjectFactory和PoolableObjectFactory形式如出一辙,只是每个方法都增加了一个Object key参数而已:
makeObject的参数变为(Object key)
activateObject的参数变为(Object key, Object obj)
passivateObject的参数变为(Object key, Object obj)
validateObject的参数变为Object key, Object obj)
destroyObject的参数变为(Object key, Object obj)
另外Pool组件也提供了BaseKeyedPoolableObjectFactory,用于充当和BasePoolableObjectFactory差不多的角色。
KeyedObjectPool和ObjectPool的形式大同小异,只是某些方法的参数类型发生了变化,某些方法分成了两种略有不同的版本:
用Object borrowObject(Object key)和void returnObject(Object key, Object obj)来负责对象出借和归还的动作。
用void close()来关闭不再需要的对象池。
用void clear(Object key)和void clear()来清空池中的对象,前者针对与特定键值相关联的实例,后者针对整个对象池。
用int getNumActive(Object key)和int getNumActive()来查询已借出的对象数,前者针对与特定键值相关联的实例,后者针对整个对象池。
用int getNumIdle(Object key)和int getNumIdle()来查询正在休眠的对象数,前者针对与特定键值相关联的实例,后者针对整个对象池。
用void setFactory(KeyedPoolableObjectFactory factory)来设置要用的KeyedPoolableObjectFactory实例。
void clear、int getNumActive、int getNumIdle和void setFactory的各种版本都仍然是可以由具体实现自行决定是否要支持的方法。如果所用的KeyedObjectPool实现不支持这些操作,那么调用这些方法的时候,会抛出一个UnsupportedOperationException异常。
KeyedObjectPoolFactory和ObjectPoolFactory的形式完全相同,只是所代表的对象不同而已。
下面我们进入编码部分:我们要做的就是利用object pool来存放数据库连接,因为数据库的连接的对象是个大对象,初始的时候需要与远程数据库交互,耗费时间和性能较大,我会在代码中详述,下面我们开始编码:
如上所说,首先我们得新建一个facotry,PoolableObjectFactory是在org.apache.commons.pool包中定义的一个接口。实际使用的时候需要利用这个接口的一个具体实现。Pool组件本身没有包含任何一种PoolableObjectFactory实现,需要根据情况自行创立。
下面我们新建个factory,用来实施对对象的管理。
package net.chinacsharp.main;
import java.sql.Connection;
import java.sql.DriverManager;
import org.apache.commons.pool.PoolableObjectFactory;
/**
*@authorkeyboardsunmail:keyboardsun@163.com
*@sitehttp://www.chinacsharp.net
*/
publicclass ObjectFactory implements PoolableObjectFactory {
Connection conn =null;
/**
*这里,我们在使用对象的时候,需要首先激活这个对象,但是在多线程情况下,
*这个对象已经被别的线程借去用了,那我们就要再建立一个对象。
*/
publicvoid activateObject(Object arg0) throws Exception {
if(conn == null)//这里,如果对象没借到,那就要新建一个了。
makeObject();
System.out.println("activateObject"+arg0);
}
/**
*这里我们销毁这个对象。不用这个对象了,这个方法得在业务使用过程中主动调用。
*在调用完这个方法过后,对象已经被销毁,但是在Objectpool里面还是存在这个对象的
*只是这个对象是null而已。所以在调用完destroyObject过后,要记得把pool清空一下。
*/
publicvoid destroyObject(Object arg0) throws Exception {
System.out.println("destroyObject"+arg0);
conn.close();
conn = null;
}
/**
*这里,在业务中第一次借对象的时候,这里要初始化一个,如果初始的都被借了,那就要继续初始
*这里创建的对象将被存到pool里面
*/
public Object makeObject() throws Exception {
System.out.println("makeObject");
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORACLEDB", "uwfe", "password");
conn.setAutoCommit(false);
return conn;
}
/**
*这里,在我们使用完每个对象过后,要做的就是归还,在归还后就要调用这个方法。
*简单的说,在还款凭证上面签个大名
*/
publicvoid passivateObject(Object arg0) throws Exception {
System.out.println("passivateObject"+arg0);
conn.commit();
}
/**
*这个方法是验证对象,这里我们不做处理,这里在借对象和还对象的时候都要验证下的。
*/
publicboolean validateObject(Object arg0) {
System.out.println("validateObject"+arg0);
returntrue;
}
}
下面我们来新建测试类
package net.chinacsharp.main;
import java.sql.Connection;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.StackObjectPool;
/**
*@authorkeyboardsunmail:keyboardsun@163.com
*@sitehttp://www.chinacsharp.net
*/
publicclass ObjectPoolSample {
publicstaticvoid main(String[] args) throws Throwable {
final ObjectFactory factory = new ObjectFactory();
final ObjectPool pool = new StackObjectPool(factory);
try{
Connection connection = null;
for(long i = 0; i <5; i++){
// 这里我们要借个对象用一下噢,第一次借的时候,要调用makeobject的噢。记得看日志
connection = (Connection)pool.borrowObject();
System.out.println("======="+i+"==="+connection+"==========");
// 这里我们要还对象噢,想知道他做了什么。记得看日志
pool.returnObject(connection);
}
} catch(Exception e){
System.out.println(e.getMessage());
}
}
}
上面的代码运行5次循环,下面我们来看看日志噢:
makeObject
activateObjectoracle.jdbc.driver.T4CConnection@19bd03e
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
=======0===oracle.jdbc.driver.T4CConnection@19bd03e==========
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
passivateObjectoracle.jdbc.driver.T4CConnection@19bd03e
activateObjectoracle.jdbc.driver.T4CConnection@19bd03e
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
=======1===oracle.jdbc.driver.T4CConnection@19bd03e==========
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
passivateObjectoracle.jdbc.driver.T4CConnection@19bd03e
activateObjectoracle.jdbc.driver.T4CConnection@19bd03e
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
=======2===oracle.jdbc.driver.T4CConnection@19bd03e==========
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
passivateObjectoracle.jdbc.driver.T4CConnection@19bd03e
activateObjectoracle.jdbc.driver.T4CConnection@19bd03e
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
=======3===oracle.jdbc.driver.T4CConnection@19bd03e==========
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
passivateObjectoracle.jdbc.driver.T4CConnection@19bd03e
activateObjectoracle.jdbc.driver.T4CConnection@19bd03e
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
=======4===oracle.jdbc.driver.T4CConnection@19bd03e==========
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
从上面我们可以看出调用过程是这样,第一次借的时候。调用makeObject方法来生成一个对象,然后第二次..次就不用生成对象了,我们看看日志就知道了,日志中的连接的后面的编号都是同一个“19bd03e”,然后调用activateObject来激活对象,其实也不能说叫激活,就是要调用这个方法,然后是验证对象调用 validateObject ,然后就借出给使用了。那么归还的过程呢?归还的过程是这样,先调用 validateObject来验证对象,然后调用 passivateObject来确认归还对象,这样一个对象的借和还的过程就是这样,such as log
makeObject
activateObjectoracle.jdbc.driver.T4CConnection@19bd03e
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
=======0===oracle.jdbc.driver.T4CConnection@19bd03e==========
validateObjectoracle.jdbc.driver.T4CConnection@19bd03e
passivateObjectoracle.jdbc.driver.T4CConnection@19bd03e
本文作者 keyboardsunmail:keyboardsun@163.com
http://www.chinacsharp.net
如需转载请标明出处,作者等信息
通过上面我们已经知道了原理,下面我们就来做个测试,用POOL和不用Pool有多大的性能差别
我们看先测试用pool的情况,我们这里请求1000次连接
测试代码:
publicstaticvoid main(String[] args) throws Throwable {
final ObjectFactory factory = new ObjectFactory();
final ObjectPool pool = new StackObjectPool(factory);
try{
long start = System.currentTimeMillis();//开始时间
Connection connection = null;
for(long i = 0; i <1000; i++){
connection = (Connection)pool.borrowObject();
System.out.println("======="+i+"==="+connection+"==========");
pool.returnObject(connection);
}
long end = System.currentTimeMillis();//结束时间
System.out.println("执行1000次连接调用所耗费的时间是:"+(end-start)+"毫秒!");
} catch(Exception e){
System.out.println(e.getMessage());
}
}
运行过后输出时间是:
执行1000次连接调用所耗费的时间是:3782毫秒!
下面我们用传统的方式来调用10次连接请求,我们看看需要多长时间
测试代码:
publicstaticvoid main(String[] args) throws Throwable {
final ObjectFactory factory = new ObjectFactory();
final ObjectPool pool = new StackObjectPool(factory);
try{
long start = System.currentTimeMillis();//开始时间
Connection connection = null;
for(long i = 0; i <10; i++){
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORACLEDB", "uwfe", "password");
System.out.println("======="+i+"==="+connection+"==========");
}
long end = System.currentTimeMillis();//结束时间
System.out.println("执行传统10次连接调用所耗费的时间是:"+(end-start)+"毫秒!");
} catch(Exception e){
System.out.println(e.getMessage());
}
}
下面的输出日志:
执行10次连接调用所耗费的时间是:18594毫秒!
通过以上的两个比较我们可以看到,使用对象池技术:
连续单线程的1000请求说耗费的时间是 3782毫秒!
传统方式的10请求所耗费的时间是 18594毫秒!
如果数据库是放在别的主机,除去网络的消耗,这个比例将会更大。这里我们也知道了建立连接所耗费的资源是巨大的。
这里的差距我就不说了,对象池对于大对象来说性能真的很好。
下面也许会有人质疑,说你这个对象池在多线程调用的时候安全么?情况怎么样呢?会不会遇到借不到的情况呢?在一个连接对象被借走的情况下,另外一个线程过来请求,那不就不行了么?呵呵,你多注意下我那个factory的代码的方法的说明就可以了。这里不再多赘述。我们看看多线程的时候的对象的使用情况吧。
下面是测试代码:
publicstaticvoid main(String[] args) throws Throwable {
final ObjectFactory factory = new ObjectFac
相关推荐
9. **DBCP和Pool组件**:这两个组件分别提供了数据库连接池和对象池服务,对于优化数据库应用的性能和资源管理具有重要作用。 学习并熟练掌握《Jakarta Commons Cookbook》中的知识点,开发者不仅可以提升个人技能...
DBCP(DataBase Connection Pool)是 apache common上的一个 java 连接池项目,也是 tomcat 使用的连接池组件,依赖 于Jakarta commons-pool 对象池机制,DBCP可以直接的在应用程序中使用。 使用DBCP会用到commons-...
### Apache Jakarta Commons 使用手册知识点详解 #### 一、概述 《Apache Jakarta Commons 使用手册》是一部详细介绍Apache Jakarta Commons项目下的各种Java组件的专业书籍。该书由Will Iverson编写,旨在为...
jakarta-commons 相关依赖包,文件列表: commons-attributes-api.jar commons-attributes-compiler.jar commons-beanutils.jar commons-codec.jar commons-collections.jar commons-dbcp.jar commons-digester.jar ...
Jakarta Commons Pool是一个用于在Java程序中实现对象池化的组件。它的基本情况是: 主要作者:Morgan Delagrange、Geir Magnusson、Craig McClanahan、Rodney Waldhoff、David Weinrich和Dirk Verbeeck 最新版本:...
DBCP(Database Connection Pool)是Apache Jakarta项目中的一个子项目,它利用了commons-pool对象池机制来实现数据库连接的复用,从而减少创建和释放数据库连接时的开销。Tomcat,一个广泛使用的Java应用服务器,...
commons-pool 提供了通用对象池接口,一个用于创建模块化对象池的工具包,以及通常的对象池实 commons-primitives java 简单类型使用的扩展 commons-proxy 创建动态代理的库 commons-scxml commons-transaction ...
commons-pool 提供了通用对象池接口,一个用于创建模块化对象池的工具包,以及通常的对象池实 commons-primitives java 简单类型使用的扩展 commons-proxy 创建动态代理的库 commons-scxml commons-transaction ...
Apache Commons DBCP(Database Connection Pool)和Apache Commons Pool是两个在Java开发中常见的开源库,主要用于数据库连接管理和对象池的实现。它们是Java应用程序尤其是Web应用中的关键组件,能够提高性能并...
9. **DBCP和POOL**:数据库连接池组件,如Commons-DBCP和Commons-POOL,它们提高了数据库连接的管理和性能,降低了资源消耗。 10. **Email组件**:发送电子邮件的工具,支持多种邮件协议,如SMTP、SMTPS等,可以...
4. `jakarta-pool-1.5.2.jar`: 这是Apache Commons Pool的核心库文件,包含了所有必需的类和接口,用于实现对象池。 5. `jakarta-pool-1.5.2-sources.jar`: 源代码jar文件,可以用于查看和理解Pool库的内部工作原理...
本篇文章将深入探讨Java对象池的实现原理,以及如何借鉴"Jakarta Commons Pool"组件来设计一个轻量级的对象池。 一、对象池的基本概念 对象池的基本工作流程包括以下几个步骤: 1. 初始化:预创建一定数量的对象并...
通过使用 Jakarta Commons Pool 组件,可以实现对象池化,减少处理对象池化时的工作量,为其它重要的工作留下更多的精力和时间。 对象池化技术的基本思路 对象池化技术的基本思路是将用过的对象保存起来,等下一次...
Iverson的这本书《Apache Jakarta Commons[E文版]》详细介绍了这些组件的使用方法和功能。 在本书中,你将深入了解到Apache Jakarta Commons的核心组件,包括但不限于: 1. **BeanUtils**: 提供了对JavaBeans操作...
它依赖于另一个Apache Commons组件——Commons Pool,这是一个通用的对象池库,用于创建对象池,DBCP就是利用这个库来管理和复用数据库连接。 **DBCP的使用步骤:** 1. **添加依赖:** 首先需要将`commons-dbcp-...
3. `commons-pool-1.6.jar`:Apache Commons Pool是通用的对象池服务,它是DBCP连接池依赖的基础。DBCP利用了Pool库来实现对象(这里是数据库连接)的池化管理,包括创建、分配、回收和销毁连接等操作。 使用DBCP...
然而,对于创建开销较小的对象,维护对象池可能反而增加不必要的复杂性和开销,因此在决定是否使用对象池化时,需要权衡利弊。 总结来说,Java对象池化通过Jakarta Commons Pool 提供了一种高效管理对象的方式,...
DBCP(DataBase Connection Pool)是 apache common上的一个 java 连接池项目,也是 tomcat 使用的连接池组件,依赖 于Jakarta commons-pool 对象池机制,DBCP可以直接的在应用程序中使用。 使用DBCP会用到commons-...
Pool和DBCP:对象池创建和使用 Pool模块(包括DBCP)提供了对象池的创建和管理机制,通过复用对象而非每次创建新实例,显著降低了系统资源消耗和提高了性能。尤其在数据库连接池的场景下,DBCP能够有效管理数据库...