我这个对象池完成功能:
1、创建一个固定大小的对象池,也就是说不允许在对象池创建以后进行容量更改。
2、客户端可以从对象池获取一个可用对象
3、客户端可以把对象交还给对象池,然后可以被其他的客户端再次使用
4、可以完成对象池的创建和销毁
有几条编程准备以注释的形式出现。
下面是我的代码:
import java.util.Enumeration;
import java.util.Vector;
public class ObjectPool {
// 对象池中存放的类型
// 遵循nested class和top-level class的使用情况
// 这个类只在ObjectPool内部使用,所以最好定义成嵌套类
private static class PooledObject {
private Object object = null;// 对象
private boolean used = false;// 是否有外部客户端正在使用,默认是没有
// 构造函数,根据一个 Object 构告一个 PooledObject 对象
public PooledObject(Object object) {
this.object = object;
}
public Object getObject() {
return object;
}
public boolean isUsed() {
return used;
}
public void setUsed(boolean used) {
this.used = used;
}
}
// 由于也只能有一个对象池,所以也要使用单例模式
// 在这里使用饿汉模式
private static ObjectPool instance = new ObjectPool();
private ObjectPool() {
}
// 得到对象池的一个单例
public static ObjectPool getInstance() {
return instance;
}
private static int maxNumOfObject = 50;// 对象池的最大数量
private static Vector objects = null;// 存放对象池中对象的可变向量
// 创建一个对象池
public synchronized void createPool() {
if (objects != null) {
return;
}
objects = new Vector();
for (int i = 0; i < maxNumOfObject; i++) {
Object obj = new Object();
objects.addElement(new PooledObject(obj));
}
}
// 返回对象池中可用的对象
public synchronized Object getUseableObject() {
// 如果对象池没有创建起来,则是不可能有对象存在的
if (null == objects) {
return null;
}
Object conn = getUsableObject(); // 获得一个可用的对象
return conn;
}
// 返回一个可用对象
private Object getUsableObject() {
// 从对象池中获得一个可用的对象
Object obj = findUsableObject();
// 没有寻找到可用对象
if (null == obj) {
return null;
}
return obj;
}
// 找到一个可用对象
private Object findUsableObject() {
Object obj = null;
PooledObject pObj = null;
// 获得对象池向量中所有的对象
Enumeration enumerate = objects.elements();
// 遍历所有的对象,看是否有可用的对象
while (enumerate.hasMoreElements()) {
pObj = (PooledObject) enumerate.nextElement();
// 如果此对象不忙,则获得它的对象并把它设为忙
if (!pObj.isUsed()) {
obj = pObj.getObject();
pObj.setUsed(true);
}
}
return obj;// 返回找到到的可用对象
}
// 返回一个对象到对象池,并且标记这个对象可用
// 也就是是说外部不再使用这个对象了,对象池要回收了,以供其他客户端使用
public void returnObject(Object obj) {
if (null == obj) {
return;
}
PooledObject pObj = null;
Enumeration enumerate = objects.elements();
// 遍历对象池中的所有对象,找到这个要返回的对象对象
while (enumerate.hasMoreElements()) {
pObj = (PooledObject) enumerate.nextElement();
// 先找到对象池中的要返回的对象对象
if (obj == pObj.getObject()) {
// 找到了 , 设置此对象为空闲状态
pObj.setUsed(false);
break;
}
}
}
// 关闭对象池,同时清空池中所有对象
public synchronized void closeObjectPool() {
// 确保对象池存在,如果不存在,返回
if (objects == null) {
return;
}
PooledObject pObj = null;
Enumeration enumerate = objects.elements();
while (enumerate.hasMoreElements()) {
// 遍历得到对象池中的对象
// 从对象池向量中删除它
pObj = (PooledObject) enumerate.nextElement();
objects.removeElement(pObj);
}
// 置对象池为空
objects = null;
}
}
下面是测试代码:
public class Main {
public static void main(String[] args) {
// 得到对象池
ObjectPool objPool = ObjectPool.getInstance();
// 在对象池中初始化50个对象,并且都设置为可用状态
objPool.createPool();
// 从对象池中拿出一个可用对象
Object obj = objPool.getUseableObject();
// 打印一下这个对象的hashCode
System.out.println("obj===" + obj.toString());
// 把这个对象还回去
objPool.returnObject(obj);
// 从对象池中拿出一个可用对象
Object obj1 = objPool.getUseableObject();
// 打印一下这个对象的hashCode
System.out.println("obj1===" + obj1.toString());
// 销毁对象池以及所有对象
objPool.closeObjectPool();
}
}
下面是我打印输出:
obj===java.lang.Object@55e55f
obj1===java.lang.Object@55e55f
结论:我们从对象池获得一个对象,然后还回去,然后再借一个,发现这两个对象是同一个。这就表明对象池编写没有问题。
但是,如果需要增加对象池的大小呢?