Commons Pool处理对象池化分析(1)
来源:互联网 发布:海思 网络摄像机 sdk 编辑:程序博客网 时间:2024/05/23 15:42
参考:
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图如下:
而键值对的结构:
- Commons Pool处理对象池化分析(1)
- commons-pool对象池(1)---总结
- 使用Jakarta Commons Pool处理对象池化(zz)
- 对象池commons-pool
- Java笔记之对象池1(commons-pool)
- 使用Jakarta Commons Pool处理对象池化
- 使用Jakarta Commons Pool处理对象池化
- 使用Jakarta Commons Pool处理对象池化
- 使用Jakarta Commons Pool处理对象池化
- 使用Jakarta Commons Pool处理对象池化(二)(zt)
- 使用Jakarta Commons Pool处理对象池化(一)(zt)
- 使用Jakarta Commons Pool处理对象池化
- 使用Jakarta Commons Pool处理对象池化
- 使用Jakarta Commons Pool处理对象池化
- 使用Jakarta Commons Pool处理对象池化
- 使用Jakarta Commons Pool处理对象池化
- 使用Jakarta Commons Pool处理对象池化
- commons-pool对象池技术
- unix下面kill oracle里面已经处于killed状态的session
- Android多媒体分析(四)AudioManager
- 双链表的实现
- Lucene06---查询
- Mysql复制表结构、表数据
- Commons Pool处理对象池化分析(1)
- onInterceptTouchEvent和onTouchEvent
- linux程序设计笔记12:POSIX线程
- jquery获取、设置iframe高度
- sql 函数练习
- Android多媒体分析(五)音乐播放器实例
- 有关Android Activity的面试题和答案
- 《Linux安装》(二)启动过程
- 搜索引擎基本了解