对象的实例化是最耗费性能的操作之一,这在过去是个大问题,现在不用再过分关注它。但当我们处理封装外部资源的对象(例如数据库连接)时,对象的创建操作则会耗费很多资源。
解决方案是重用和共享这些创建成本高昂的对象,这称为对象池模式。
PooledObject.java
/**
* @author Jay Mitter
*/
public class PooledObject<T> {
/**
* 外界使用的对象
*/
private T objection = null;
/**
* 此对象是否正在使用的标志,默认没有正在使用
*/
private boolean busy = false;
/**
* 构造函数,池化对象
*
* @param objection
*/
public PooledObject(T objection) {
this.objection = objection;
}
/**
* 返回此对象中的对象
*
* @return
*/
public T getObject() {
return objection;
}
/**
* 设置此对象的,对象
*
* @param objection
*/
public void setObject(T objection) {
this.objection = objection;
}
/**
* 获得对象对象是否忙
*
* @return
*/
public boolean isBusy() {
return busy;
}
/**
* 设置对象的对象正在忙
*
* @param busy
*/
public void setBusy(boolean busy) {
this.busy = busy;
}
}
AbstractObjectPool.java
/**
* @author Jay Mitter
* @description: 抽象类对象池
*/
public abstract class AbstractObjectPool<T> {
/**
* 对象池的大小
*/
public static int numObjects = 10;
/**
* 对象池最大的大小
*/
public static int maxObjects = 50;
/**
* 存放对象池中对象的向量(PooledObject类型)
*/
protected Vector<PooledObject<T>> objects = null;
public AbstractObjectPool() {
}
/**
* 创建一个对象池
*/
public synchronized void createPool() {
// 确保对象池没有创建。如果创建了,保存对象的向量 objects 不会为空
if (objects != null) {
// 如果己经创建,则返回
return;
}
// 创建保存对象的向量,初始时有 0 个元素
objects = new Vector<PooledObject<T>>();
for (int i = 0; i < numObjects; i++) {
objects.addElement(create());
}
}
/**
* 为了泛化处理,这个对象池是个抽象类
*
* @return PooledObject<T>
*/
public abstract PooledObject<T> create();
public synchronized T getObject() {
// 确保对象池己被创建
if (objects == null) {
// 对象池还没创建,则返回 null
return null;
}
// 获得一个可用的对象
T t = getFreeObject();
// 如果目前没有可以使用的对象,即所有的对象都在使用中
while (t == null) {
// 等待250 ms
wait(250);
// 重新再试,直到获得可用的对象
t = getFreeObject();
// getFreeObject() 如果返回的为 null,则表明创建一批对象后也不可获得可用对象
}
// 返回获得的可用的对象
return t;
}
/**
* 本函数从对象池对象 objects 中返回一个可用的的对象,如果 当前没有可用的对象,则创建几个对象,并放入对象池中。
* 如果创建后,所有的对象都在使用中,则返回 null
*/
private T getFreeObject() {
// 从对象池中获得一个可用的对象
T obj = findFreeObject();
if (obj == null) {
// 如果目前对象池中没有可用的对象,创建一些对象
createObjects(10);
// 重新从池中查找是否有可用对象
obj = findFreeObject();
}
// 如果创建对象后仍获得不到可用的对象,则返回 null
return obj;
}
public void createObjects(int increment) {
for (int i = 0; i < increment; i++) {
if (objects.size() > maxObjects) {
return;
}
objects.addElement(create());
}
}
/**
* 查找对象池中所有的对象,查找一个可用的对象, 如果没有可用的对象,返回 null
*/
private T findFreeObject() {
T obj = null;
PooledObject<T> pObj = null;
// 获得对象池向量中所有的对象
Enumeration<PooledObject<T>> enumerate = objects.elements();
// 遍历所有的对象,看是否有可用的对象
while (enumerate.hasMoreElements()) {
pObj = (PooledObject<T>) enumerate.nextElement();
// 如果此对象不忙,则获得它的对象并把它设为忙
if (!pObj.isBusy()) {
obj = pObj.getObject();
pObj.setBusy(true);
break;
}
}
// 返回找到到的可用对象
return obj;
}
/**
* 此函数返回一个对象到对象池中,并把此对象置为空闲。 所有使用对象池获得的对象均应在不使用此对象时返回它。
*/
public void returnObject(T obj) {
// 确保对象池存在,如果对象没有创建(不存在),直接返回
if (objects == null) {
return;
}
PooledObject<T> pObj = null;
Enumeration<PooledObject<T>> enumerate = objects.elements();
// 遍历对象池中的所有对象,找到这个要返回的对象对象
while (enumerate.hasMoreElements()) {
pObj = (PooledObject<T>) enumerate.nextElement();
// 先找到对象池中的要返回的对象对象
if (obj == pObj.getObject()) {
// 找到了,设置此对象为空闲状态
pObj.setBusy(false);
break;
}
}
}
/**
* 关闭对象池中所有的对象,并清空对象池。
*/
public synchronized void closeObjectPool() {
// 确保对象池存在,如果不存在,返回
if (objects == null) {
return;
}
PooledObject<T> pObj = null;
Enumeration<PooledObject<T>> enumerate = objects.elements();
while (enumerate.hasMoreElements()) {
pObj = (PooledObject<T>) enumerate.nextElement();
// 如果忙,等 0.5 秒
if (pObj.isBusy()) {
// 等
wait(500);
}
// 从对象池向量中删除它
objects.removeElement(pObj);
}
// 置对象池为空
objects = null;
}
/**
* 使程序等待给定的毫秒数
*/
private void wait(int mSeconds) {
try {
Thread.sleep(mSeconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
DefaultObjectPool.java
/**
* @author Jay Mitter
*/
public class DefaultObjectPool extends AbstractObjectPool<String> {
@Override
public PooledObject<String> create() {
return new PooledObject<String>(new String("" + 1));
}
}
测试:
/**
* 创建型模式——对象池模式
*/
@Test
public void testBuilderObjectPool() {
AbstractObjectPool<String> objPool = new DefaultObjectPool();
objPool.createPool();
for (int i = 0; i < 15; i++) {
String obj = objPool.getObject();
System.out.println(obj);
objPool.returnObject(obj);
}
objPool.closeObjectPool();
}
网友评论