Commons Pool处理对象池化分析(1)
2012-03-16 11:53
120 查看
参考:
http://www.ibm.com/developerworks/cn/java/l-common-pool/ http://www.blogjava.net/changedi/archive/2011/05/06/349665.html
对象池化技术:
将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用,从而在一定程度上减少频繁创建对象所造成的开销。用于充当保存对象的“容器”的对象,被称为“对象池”(Object Pool,或简称Pool)。
为什么要使用池化技术:
有时候初始化一些对象可以能会消耗很多的时间,比如对数据库的操作需要 :
1、和数据库建立连接
2、对数据进行查询
3、和数据库断开连接
一般情况下数据库和java程序都不在一台机器上,这个时候需要通过网络来访问,建立连接消耗的时间比较长,如果每次查询都需要重新建立连接,不仅服务器压力最大,
而且对于用户来说,过慢的访问速度大大影响了体验效果。
这个时候就需要使用池化技术来加快访问速度,原理:在系统启动的时候建立若干个数据库连接的对象并且保存起来(若干的概念就引申为“池”可以是List等),某个用户需要对数据库操作的时候直接在这个“池”里面拿到一个连接对象,待操作完成之后,将这个连接归还给“池”。这样一来程序和数据库建立连接对象的时间交给了系统启动,完成之后不直接销毁而是放回原处,这样用户和数据库建立连接的过程,转变为了从“池”里面拿放的过程,大大提供了服务器效率,从而增强了用户体验。
使用commons-pool实现连接池:
下载地址:http://commons.apache.org/pool/
Commons-Pool 提供了通用对象池接口,一个用于创建模块化对象池的工具包,以及通常的对象池实
所含包数:2个(org.apache.commons.pool和org.apache.commons.pool.impl)
所含类数:21个(其中有4个抽象类和6个接口)
如果使用池化技术的话一般涉及到如下几个接口:
PoolableObjectFactory、ObjectPool和ObjectPoolFactory
在Pool组件中,对象池化的工作被划分给了三类对象:
PoolableObjectFactory用于管理被池化的对象的产生、激活、挂起、校验和销毁;
ObjectPool用于管理要被池化的对象的借出和归还,并通知PoolableObjectFactory完成相应的工作;
ObjectPoolFactory则用于大量生成相同类型和设置的ObjectPool。
相应地,使用Pool组件的过程,也大体可以划分成“创立PoolableObjectFactory”、“使用ObjectPool”和可选的“利用ObjectPoolFactory”三种动作。
举个实际点的例子说明 这几个类之间的关系,电脑向手机、移动硬盘等移动设备复制文件,这些移动产品最终都是通过统一的usb接口跟电脑连接,可见和电脑相连的那一端接口是统一,只不过和不同设备连接的那一端不同而已,因此各大移动设备厂商只要保证和电脑连接的那端接口是统一就行,至于和各种移动设备连接的那一段是什么口都不要紧,这个做好了电脑就可以对移动设备的存储空间进行操作了,怎么操作是电脑的事情和移动设备无关。
PoolableObjectFactory相当于和电脑连接的那一端usb,各大移动厂商根据自己设备的特点实现PoolableObjectFactory接口里面的方法就可以和电脑连接了,而ObjectPool相当于电脑,将PoolableObjectFactory的实例放在里面,电脑就可以操作移动设备了。
同理比如一个Bean需要使用池化技术来管理,对于这个Bean对象只要实现PoolableObjectFactory接口,而具体怎么去产生、激活、挂起、校验和销毁,的操作是这个Bean对象自己的业务。
将PoolableObjectFactory接口的引用放在ObjectPool里面(一般在实例化ObjectPool或者通过ObjectPool的setFactory方法将其设置进去),由此可知这个对象实际上是用来管理被池化对象的(对象借出和归还),相当于电脑管理移动设备一样。
被池化的对象是通过实现PoolableObjectFactory来完成的,如果需要生成大量相同设置和类型的ObjectPool(相当于生产电脑)最好是用ObjectPoolFactory工厂来创建。
最简单池化技术的使用:
1、创建一个实现了PoolableObjectFactory接口的类PoolableObjectFactorySample被池化对象是StringBuilder。
PoolableObjectFactory 包括
2、开始池化:
StackObjectPool实现了ObjectPool接口,是系统默认定义里面保存所有池化了的对象,用Stack(堆)来存储,主要方法:
很多时候我们不需要实现PoolableObjectFactory接口里面的所有方法, 幸好系统提供了 BasePoolableObjectFactory我们只需要继承就行了,根据具体情况编写代码。
例如:
UML图
根据设计模式来考虑:
PoolableObjectFactory相当于产品的工厂,负责产品的细节部分。
而ObjectPool相当于管理在PoolableObjectFactory中生产出来的产品
而ObjectPoolFactory就是生产管理者的工厂。
与此对应这些接口有的有抽象的类:
PoolableObjectFactory------BasePoolableObjectFactory
ObjectPool---------------------BaseObjectPool
如果就存储接口来讲应该包括:数组、链表、键值对。
UML图如下:
![](http://hi.csdn.net/attachment/201203/16/0_1331870591J2El.gif)
而键值对的结构:
http://www.ibm.com/developerworks/cn/java/l-common-pool/ http://www.blogjava.net/changedi/archive/2011/05/06/349665.html
对象池化技术:
将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用,从而在一定程度上减少频繁创建对象所造成的开销。用于充当保存对象的“容器”的对象,被称为“对象池”(Object Pool,或简称Pool)。
为什么要使用池化技术:
有时候初始化一些对象可以能会消耗很多的时间,比如对数据库的操作需要 :
1、和数据库建立连接
2、对数据进行查询
3、和数据库断开连接
一般情况下数据库和java程序都不在一台机器上,这个时候需要通过网络来访问,建立连接消耗的时间比较长,如果每次查询都需要重新建立连接,不仅服务器压力最大,
而且对于用户来说,过慢的访问速度大大影响了体验效果。
这个时候就需要使用池化技术来加快访问速度,原理:在系统启动的时候建立若干个数据库连接的对象并且保存起来(若干的概念就引申为“池”可以是List等),某个用户需要对数据库操作的时候直接在这个“池”里面拿到一个连接对象,待操作完成之后,将这个连接归还给“池”。这样一来程序和数据库建立连接对象的时间交给了系统启动,完成之后不直接销毁而是放回原处,这样用户和数据库建立连接的过程,转变为了从“池”里面拿放的过程,大大提供了服务器效率,从而增强了用户体验。
使用commons-pool实现连接池:
下载地址:http://commons.apache.org/pool/
Commons-Pool 提供了通用对象池接口,一个用于创建模块化对象池的工具包,以及通常的对象池实
所含包数:2个(org.apache.commons.pool和org.apache.commons.pool.impl)
所含类数:21个(其中有4个抽象类和6个接口)
如果使用池化技术的话一般涉及到如下几个接口:
PoolableObjectFactory、ObjectPool和ObjectPoolFactory
在Pool组件中,对象池化的工作被划分给了三类对象:
PoolableObjectFactory用于管理被池化的对象的产生、激活、挂起、校验和销毁;
ObjectPool用于管理要被池化的对象的借出和归还,并通知PoolableObjectFactory完成相应的工作;
ObjectPoolFactory则用于大量生成相同类型和设置的ObjectPool。
相应地,使用Pool组件的过程,也大体可以划分成“创立PoolableObjectFactory”、“使用ObjectPool”和可选的“利用ObjectPoolFactory”三种动作。
举个实际点的例子说明 这几个类之间的关系,电脑向手机、移动硬盘等移动设备复制文件,这些移动产品最终都是通过统一的usb接口跟电脑连接,可见和电脑相连的那一端接口是统一,只不过和不同设备连接的那一端不同而已,因此各大移动设备厂商只要保证和电脑连接的那端接口是统一就行,至于和各种移动设备连接的那一段是什么口都不要紧,这个做好了电脑就可以对移动设备的存储空间进行操作了,怎么操作是电脑的事情和移动设备无关。
PoolableObjectFactory相当于和电脑连接的那一端usb,各大移动厂商根据自己设备的特点实现PoolableObjectFactory接口里面的方法就可以和电脑连接了,而ObjectPool相当于电脑,将PoolableObjectFactory的实例放在里面,电脑就可以操作移动设备了。
同理比如一个Bean需要使用池化技术来管理,对于这个Bean对象只要实现PoolableObjectFactory接口,而具体怎么去产生、激活、挂起、校验和销毁,的操作是这个Bean对象自己的业务。
将PoolableObjectFactory接口的引用放在ObjectPool里面(一般在实例化ObjectPool或者通过ObjectPool的setFactory方法将其设置进去),由此可知这个对象实际上是用来管理被池化对象的(对象借出和归还),相当于电脑管理移动设备一样。
被池化的对象是通过实现PoolableObjectFactory来完成的,如果需要生成大量相同设置和类型的ObjectPool(相当于生产电脑)最好是用ObjectPoolFactory工厂来创建。
最简单池化技术的使用:
1、创建一个实现了PoolableObjectFactory接口的类PoolableObjectFactorySample被池化对象是StringBuilder。
public class PoolableObjectFactorySample implements PoolableObjectFactory<StringBuilder> { private static int counter = 0; /** * 这个方法用于在必要时产生新的对象 */ public StringBuilder makeObject() throws Exception { StringBuilder obj = new StringBuilder(); obj.append(counter++); System.err.println("Making Object " + obj.toString()); return obj; } /** * 这个方法用于销毁被validateObject判定为已失效的对象 */ public void destroyObject(StringBuilder obj) throws Exception { System.err.println("Destroying Object " + obj); } /** * 这个方法用于校验一个具体的对象是否仍然有效,已失效的对象会被自动交给destroyObject方法销毁 */ public boolean validateObject(StringBuilder obj) { /* 以1/2的概率将对象判定为失效 */ boolean result = (Math.random() > 0.5); System.err.println("Validating Object " + obj + " : " + result); return result; } /** * 这个方法用于将对象“激活”――设置为适合开始使用的状态 */ public void activateObject(StringBuilder obj) throws Exception { System.err.println("Activating Object " + obj); } /** * 这个方法用于将对象“挂起”――设置为适合开始休眠的状态 */ public void passivateObject(StringBuilder obj) throws Exception { System.err.println("Passivating Object " + obj); } }
PoolableObjectFactory 包括
创建 T makeObject() 池化对象。 销毁 destroyObject(T obj)池化对象。 验证 boolean validateObject(T obj)池化对象。 激活void activateObject(T obj)池化对象
2、开始池化:
public class ObjectPoolSample { /** * @param args */ public static void main(String[] args) { // 生成一个要PoolableObjectFactory类的实例 PoolableObjectFactory<StringBuilder> factory = new PoolableObjectFactorySample(); // 利用这个PoolableObjectFactory实例为参数, //生成一个实现了ObjectPool接口的类(例如StackObjectPool)的实例,作为对象池 ObjectPool<StringBuilder> pool = new StackObjectPool<StringBuilder>(factory); //使用StackObjectPool工厂来实现 //ObjectPoolFactory poolFactory = new StackObjectPoolFactory(factory); //ObjectPool pool = poolFactory.createPool(); StringBuilder obj = null; try { for (long i = 0; i < 100; i++) { System.out.println("== " + i + " =="); // 需要从对象池中取出对象时,调用该对象池的Object borrowObject()方法。 obj = pool.borrowObject(); System.out.println(obj.toString()); if((i&1)==0) // 需要将对象放回对象池中时,调用该对象池的void returnObject(Object obj)方法 pool.returnObject(obj); System.out.println(obj); } obj = null;// 明确地设为null,作为对象已归还的标志 // 当不再需要使用一个对象池时,调用该对象池的void close()方法,释放它所占据的资源。 } catch (Exception e) { e.printStackTrace(); } finally { try { if (obj != null) {// 避免将一个对象归还两次 pool.returnObject(obj); } pool.close(); } catch (Exception ex) { ex.printStackTrace(); } } } }
StackObjectPool实现了ObjectPool接口,是系统默认定义里面保存所有池化了的对象,用Stack(堆)来存储,主要方法:
T borrowObject()从池中获取一个对象。 void returnObject(T obj) 将使用了的对象放入池中。 void invalidateObject(T obj) 销毁某个对象。 void close()来关闭不再需要的对象池 void clear()来清空池中的对象。 int getNumActive()来查询已借出的对象数。 int getNumIdle()来查询正在休眠的对象数。 void setFactory(PoolableObjectFactory factory)来设置要用的PoolableObjectFactory实例
很多时候我们不需要实现PoolableObjectFactory接口里面的所有方法, 幸好系统提供了 BasePoolableObjectFactory我们只需要继承就行了,根据具体情况编写代码。
例如:
public class BasePoolableObjectFactorySample extends BasePoolableObjectFactory { private int counter = 0; public Object makeObject() throws Exception { return String.valueOf(counter++); } }我们只需要实现makeObject方法。
UML图
根据设计模式来考虑:
PoolableObjectFactory相当于产品的工厂,负责产品的细节部分。
而ObjectPool相当于管理在PoolableObjectFactory中生产出来的产品
而ObjectPoolFactory就是生产管理者的工厂。
与此对应这些接口有的有抽象的类:
PoolableObjectFactory------BasePoolableObjectFactory
ObjectPool---------------------BaseObjectPool
如果就存储接口来讲应该包括:数组、链表、键值对。
UML图如下:
![](http://hi.csdn.net/attachment/201203/16/0_1331870591J2El.gif)
而键值对的结构:
![](http://hi.csdn.net/attachment/201203/16/0_1331870601Tiu7.gif)
相关文章推荐
- BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象)
- BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象) -- 转贴自 wolfenstein (NeverSayNever)
- 锁对象-Lock: 同步问题更完美的处理方式 (ReentrantReadWriteLock读写锁的使用/源码分析)
- Ajax详解及其案例分析之如何获得Ajax对象,使用Ajax对象发送GET和POST请求,校验用户名,POST和GET请求时的乱码处理,实现级联的下拉列表
- Tomcat处理HTTP请求源码分析--包含jsp内置对象的实例过程
- 使用Jakarta Commons Pool处理对象池化(二)(zt)
- 使用Jakarta Commons Pool处理对象池化(一)(zt)
- 《cv中文参考手册-图像轮廓处理-结构分析与形状识别-获取各个对象的质心》HuMoments
- BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象) -- 转贴自 wolfenstein (NeverSayNever)
- 【unity】【NGUI】当把挂在比如UILabel之类NGUI组件的对象对象池化的时候,出现各种问题的原因分析
- Tomcat处理HTTP请求源码分析--包含jsp内置对象的实例过程
- BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象)
- BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象)
- 使用Jakarta Commons Pool处理对象池化(zz)
- Spring AOP在函数接口调用性能分析及其日志处理方面的应用
- Android异步消息处理机制详解及源码分析
- Tomcat处理HTTP请求源码分析(下)
- 电脑经常死机的原因与故障处理分析
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- 日志文件的处理和分析