开发中,我们有时会频繁重复创建一些对象,而对象又有比较多的属性,为避免频繁创建对象带来的开销,我们可以采用对象池技术,将创建的对象进行缓存复用。
采用对象池技术,我们一般需要做两步操作:
1、获得对象
如果对象池中存在对象,就消费一个对象。
如果对象池中没有对象,则创建一个对象,用完后放入对象池中。
2、归还对象
对象使用完后,重置对象属性,以便复用,然后归还到对象池中
下面举2个简单的实例,对象池技术本身是一种思想,并不限定以那种方式实现,希望大家领会到这种思想后,实现自己的对象池。
/**
* 一个基于List的对象池实现
* @author zhangquanit
*/
public class TargetObject {
private final static int maxSize = 100; //最大对象个数
private static final List<TargetObject> objectPool = new ArrayList<>();
private String param1; //属性1
private boolean param2; //属性2
/*为避免调用者随意创建对象,且不放入对象池中,将构造方法私有化*/
private TargetObject(String param1, boolean param2) {
this.param1 = param1;
this.param2 = param2;
}
public static TargetObject obtain(String param1, boolean param2) {
synchronized (objectPool) {
int size = objectPool.size();
if (size > 0) {
// 从对象池中拿到一个对象
TargetObject object = objectPool.remove(size - 1);//消费对象
//赋值属性
object.param1 = param1;
object.param2 = param2;
return object;
}
}
return new TargetObject(param1, param2);// 当对象池中的对象不够用时,创建一个对象
}
/**
* 重置属性,以便复用对象
*/
private void reset() {
this.param1 = null;
this.param2 = false;
}
/**
* 将对象归还到对象池中
* @param object
*/
public static void releaseObject(TargetObject object) {
object.reset();
synchronized (objectPool) {
if (objectPool.size() < maxSize) {
objectPool.add(object);
}
}
}
}
/**
* 一个基于数组的对象池实现
* @author zhangquanit
*/
public class TargetObject2 {
private final static int maxSize = 100; //最大对象个数
private static final TargetObject2[] objectPool=new TargetObject2[maxSize];
private String param1; //属性1
private boolean param2; //属性2
/*为避免调用者随意创建对象,且不放入对象池中,将构造方法私有化*/
private TargetObject2(String param1, boolean param2) {
this.param1 = param1;
this.param2 = param2;
}
public static TargetObject2 obtain(String param1, boolean param2) {
synchronized (objectPool) {
for(int i=0;i<maxSize;i++){
TargetObject2 object=objectPool[i];
if(null!=object){
objectPool[i]=null;//消费对象
object.param1=param1;
object.param2=param2;
return object;
}
}
}
return new TargetObject2(param1, param2);// 当对象池中的对象不够用时,创建一个对象
}
/**
* 重置属性,以便复用对象
*/
private void reset() {
this.param1 = null;
this.param2 = false;
}
/**
* 将对象归还到对象池中
* @param object
*/
public static void releaseObject(TargetObject2 object) {
object.reset();
synchronized (objectPool) {
for(int i=0;i<maxSize;i++){
if(objectPool[i]==null){
objectPool[i]=object;
}
}
}
}
}
由于构造方法都私有化了,我们只能通过obtain来获取对象
//获取对象
TargetObject targetObject = TargetObject.obtain("参数1", true);
//对象使用完毕后,归还对象到对象池中
TargetObject.releaseObject(targetObject);