一、背景介绍
创建新的对象并初始化的操作,可能会消耗很多的时间。在需要频繁创建并使用这些对象的场景中,为了提供系统性能,通常的做法是,创建一个对象池,将一定数量的对象缓存到这个对象池中。需要使用时直接从对象池中取出对象,使用完后将对象扔回到对象池中即可。Apache的commons pool组件是我们实现对象池化技术的良好助手。
二、组件基本介绍
该项目是一个基本的对象池组件;Pool提供三个主要方面对象池的API:
a) 一个提供客户方和实现方用来实现简单、可变的对象池的基本接口。
b) 一个用来创建模块化对象池的工具。
c) 几个通用的对象池的实现。
三、组件特点
org.apache.commons.pool包定义了一部分在创建一个新的对象池实现时十分有用的接口和基本类。
四、对象池
(1)ObjectPool
ObjectPool定义了一个简单小巧的池化接口,主要有GenericObjectPool、StackObjectPool、SoftReferenceObjectPool三个实现类;
a)GenericObjectPool:可配置LIFO/FIFO行为的ObjectPool的实现。默认采用LIFO队列方式。这意味着当有闲置的可用对象在对象池中时,borrowObject方法会返回最近的实例。如果配置文件中的lifo配置项的值为false,则将返回相反排序的实例,也就是会返回最先进入对象池的对象的实例。
b)StackObjectPool:使用LIFO行为实现的ObjectPool。
c)SoftReferenceObjectPool:使用LIFO行为实现的ObjectPool。此外,在这个对象池实现中,每个对象都会被包装到一个SoftReference中。SoftReference允许垃圾回收机制在需要释放内存时回收对象池中的对象。
(2)KeyedObjectPool
KeyedObjectPool对象池有多种类型情况的对象池的实现,每种类型对应一个任意的键值,组件给出了GenericKeyedObjectPool、StackKeyedObjectPool两个基本的实现类;
a)GenericKeyedObjectPool:通过FIFO行为实现的对象池。
b)StackKeyedObjectPool:通过LIFO行为实现的对象池。
五、PoolableObjectFactory、ObjectPool及ObjectPoolFactory
在commons pool组件中,对象池化的工作被划分给了三类对象: PoolableObjectFactoryExample.java
(1) PoolableObjectFactory用于管理池化对象的产生、激活、挂起、校验和销毁;
(2) ObjectPool用于管理要被池化的对象的借出和归还,同时通知PoolableObjectFactory完成相应的工作;
(3) ObjectPoolFactory则用于大量生成相同类型和设置的ObjectPool;
相应的,使用Pool组件的过程,也可大体划分成“实现自己的PoolableObjectFactory”、“使用
ObjectPool”和可选的“利用ObjectPoolFactory”三个步骤。
(1) 实现自己的PoolableObjectFactory
ObjectPool的实例在需要处理池化的对象的产生、激活、挂起、校验和销毁工作时,就会调用跟它
关联在一起的PoolableObjectFactory实例的相应方法来操作。PoolableObjectFactory是commons-pool
中定义个一个接口,Pool组件中没有包含任何一种PoolableObjectFactory实现,需要根据情况自行创立。
// 该方法用于产生你要放入到对象池中的新对象
Object makeObject() throws Exception;
// 该方法用于销毁对象
void destroyObject(Object obj) throws Exception;
/** 该方法用于校验对象是否有效,对于失效的对象会调用
* destroyObject方法进行销毁
*/
boolean validateObject(Object obj);
/** 该方法用于将对象“激活”,对于可变对象,该方法主要是
* 对象恢复成初始状态
*/
void activateObject(Object obj) throws Exception;
// 该方法用于将对象“挂起”,将对象设置为休眠状态即不可用
void passivateObject(Object obj) throws Exception;
ObjectPool是Pool组件中定义的一个接口,实际使用的时候同样需要利用这个接口的具
体实现。Pool组件本身提供了几种实现,可以直接使用。当然也可以自行创建。
ObjectPool的使用方法:
(a)、 生成一个要用的PoolableObjectFactory类的实例
PoolableObjectPoolFactory factory = new PoolableObjectPoolFactoryExample();
(b)、 利用PoolableObjectPoolFactory实例为参数,生成一个实现了ObjectPool接口的类的实
例,作为对象池ObjectPool pool = new StackObjectPool(factory);
(c)、 需要从对象池中获取对象时,调用对应的borrowObject()方法Object obj = pool.borrowObject();
(d)、 将对象放回对象池中,调用returnObject(Object obj)方法pool.returnObject(obj);
(e)、 当不再需要对象池时,直接调用对象池上的close()方法,释放资源。pool.close();
另外,ObjectPool接口还定义了几个可以由具体的实现决定要不要支持的操作,包括:
void clear()
清除所有当前在此对象池中休眠的对象。
int getNumActive()
返回已经从此对象池中借出的对象的总数。
int getNumIdle()
返回当前在此对象池中休眠的对象的数目。
void setFactory(PoolableObjectFactory factory)
将当前对象池与参数中给定的PoolableObjectFactory相关联。如果在当前状态下,无法
完成这一操作,会有一个IllegalStateException异常抛出。
(3)使用ObjectPoolFactory
ObjectPoolFactory是Pool组件中定义的一个接口,它定义了一个createPool()方法,可以
用于大量产生类型和设置都相同的ObjectPool的对象。
Pool组件中,对每一个ObjectPool的实现,都有一个对应的ObjectPoolFactory实现。
最后给出一个较为完整的例子:
package org.apache.commons.pool;
public class PoolableObjectFactoryExample implements PoolableObjectFactory
{
/**
* 一个简单的实现PoolableObjectPool接口的例子
*/
private static int count = 0;
/**
* 将对象设置为激活状态
* 对于可变对象,可以使用编码方式将对象转变为初始状态
*/
@Override
public void activateObject(Object obj) throws Exception
{
System.out.println("destroyObject run + " + obj);
}
/**
* 销毁池化对象的方法
*/
@Override
public void destroyObject(Object obj) throws Exception
{
System.out.println("destroyObject run + " + obj);
}
/**
* 创建池化对象的方法
*/
@Override
public Object makeObject() throws Exception
{
String obj = String.valueOf(count);
System.out.println("makeObject run + " + obj);
return obj;
}
/**
* 将池化对象设置为休眠状态,表示该对象不可用
*/
@Override
public void passivateObject(Object obj) throws Exception
{
System.out.println("passivateObject run + " + obj);
}
/**
* 校验池化对象是否可用的方法
*/
@Override
public boolean validateObject(Object obj)
{
boolean flag = false;
if(obj.equals(obj))
{
flag = true;
}
return flag;
}
}
ObjectPoolExample.java
package org.apache.commons.pool;
import org.apache.commons.pool.impl.StackObjectPoolFactory;
public class ObjectPoolExample
{
public static void main(String[] args)
{
// 生成PoolableObjectFactory实例
PoolableObjectFactory _factory = new PoolableObjectFactoryExample();
// 生成一个ObjectPoolFactory实例
ObjectPoolFactory objFactory = new StackObjectPoolFactory(_factory);
// 生成一个ObjectPool实例
ObjectPool pool = objFactory.createPool();
// 获取对象池中的一个可用对象
try
{
Object obj = pool.borrowObject();
// 使用对象
pool.returnObject(obj);
obj = null;
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
try
{
// 关闭对象池
pool.close();
pool = null;
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}