一、对象池概述:
对于那些实例化开销比较大,并且生命周期比较短的对象,我们可以通过池就行管理。所谓池,就相当于一个仓库,里面的东西是有借有还的。这样可以控制池内对象的数量,开销,并且一个对象实例可以重复使用。
二、自定义连接池:
1.一个连接池对象,它应该具备一个繁忙状态,并且我拥有获取这个对象,判断繁忙状态,设置繁忙状态的api.
package com.example.springboot1.objectPool;
public class PoolObject {
private T objection =null;// 外界使用的对象
private boolean busy =false; // 此对象是否正在使用的标志,默认没有正在使用
// 构造函数,池化对象
public PoolObject(T objection) {
this.objection = objection;
}
// 返回此对象中的对象
public T getObject() {
return objection;
}
// 设置此对象的,对象
public void setObject(T objection) {
this.objection = objection;
}
// 获得对象对象是否忙
public boolean isBusy() {
return busy;
}
// 设置对象的对象正在忙
public void setBusy(boolean busy) {
this.busy = busy;
}
}
2.对象池,一个对象池,它需要一些基本配置熟悉,如最大连接数,空闲数,超时时间等等,并且需要创建池,关系池,创建对象,归还对象,获取空闲对象,统计等相关api。
package com.example.springboot1.objectPool;
import com.example.springboot1.objectPool.PoolObject;
import java.util.Enumeration;
import java.util.Vector;
public abstract class ObjectPool {
public static int numObjects =10; // 对象池的大小
public static int maxObjects =50; // 对象池最大的大小
protected Vector>objects =null; // 存放对象池中对象的向量(PooledObject类型)
public ObjectPool() {
}
/*** 创建一个对象池 ***/
public synchronized void createPool() {
// 确保对象池没有创建。如果创建了,保存对象的向量 objects 不会为空
if (objects !=null) {
return; // 如果己经创建,则返回
}
// 创建保存对象的向量 , 初始时有 0 个元素
objects =new Vector>();
for (int i =0; i
objects.addElement(create());
}
}
public abstract PoolObjectcreate();
public synchronized T getObject() {
// 确保对象池己被创建
if (objects ==null) {
return null; // 对象池还没创建,则返回null
}
T t = getFreeObject(); // 获得一个可用的对象
// 如果目前没有可以使用的对象,即所有的对象都在使用中
while (t ==null) {
wait(250);
t = getFreeObject(); // 重新再试,直到获得可用的对象,如果
// getFreeObject() 返回的为 null,则表明创建一批对象后也不可获得可用对象
}
return t;// 返回获得的可用的对象
}
/**
* 本函数从对象池对象 objects 中返回一个可用的的对象,如果 当前没有可用的对象,则创建几个对象,并放入对象池中。
* 如果创建后,所有的对象都在使用中,则返回 null
*/
private T getFreeObject() {
// 从对象池中获得一个可用的对象
T obj = findFreeObject();
if (obj ==null) {
createObjects(10); // 如果目前对象池中没有可用的对象,创建一些对象
// 重新从池中查找是否有可用对象
obj = findFreeObject();
// 如果创建对象后仍获得不到可用的对象,则返回null
if (obj ==null) {
return 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;
PoolObject pObj =null;
// 获得对象池向量中所有的对象
Enumeration> enumerate =objects.elements();
// 遍历所有的对象,看是否有可用的对象
while (enumerate.hasMoreElements()) {
pObj = (PoolObject) enumerate.nextElement();
// 如果此对象不忙,则获得它的对象并把它设为忙
if (!pObj.isBusy()) {
obj = pObj.getObject();
pObj.setBusy(true);
}
}
return obj;// 返回找到到的可用对象
}
/**
* 此函数返回一个对象到对象池中,并把此对象置为空闲。 所有使用对象池获得的对象均应在不使用此对象时返回它。
*/
public void returnObject(T obj) {
// 确保对象池存在,如果对象没有创建(不存在),直接返回
if (objects ==null) {
return;
}
PoolObject pObj =null;
Enumeration> enumerate =objects.elements();
// 遍历对象池中的所有对象,找到这个要返回的对象对象
while (enumerate.hasMoreElements()) {
pObj = (PoolObject) enumerate.nextElement();
// 先找到对象池中的要返回的对象对象
if (obj == pObj.getObject()) {
// 找到了 , 设置此对象为空闲状态
pObj.setBusy(false);
break;
}
}
}
/**
* 关闭对象池中所有的对象,并清空对象池。
*/
public synchronized void closeObjectPool() {
// 确保对象池存在,如果不存在,返回
if (objects ==null) {
return;
}
PoolObject pObj =null;
Enumeration> enumerate =objects.elements();
while (enumerate.hasMoreElements()) {
pObj = (PoolObject) 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) {
}
}
}
3.开源的池工具,apach commons-pool
继承BasePooledObjectFactory或者PooledObjectFactory,实现makeObject方法。
public class IntellifObjectPoolFactory implements PooledObjectFactory {
private ClasstClass;
private T obj;
@Override
public PooledObjectwrap(T t) {
return null;
}
@Override
public PooledObjectmakeObject()throws Exception {
return new DefaultPooledObject(this.obj);
}
@Override
public void destroyObject(PooledObject pooledObject)
throws Exception {
}
@Override
public boolean validateObject(PooledObject pooledObject) {
//默认是false,代表验证不通过,这里随机好了
return new Random().nextInt()%2==0;
}
@Override
public void activateObject(PooledObject pooledObject)
throws Exception {
}
@Override
public void passivateObject(PooledObject pooledObject)
throws Exception {
}
}
创建代理池对象IntellifObjectPool
public class IntellifObjectPool {
private static ConcurrentHashMappoolSet =new ConcurrentHashMap<>();
private StringpoolName;
private int maxTotal;
private GenericObjectPoolgenericObjectPool;
private ClasstClass;
private T obj;
public IntellifObjectPool(String poolName,Integer maxTotal,T obj)throws ClassNotFoundException {
if(IntellifObjectPool.poolSet.get(poolName)!=null){
this.genericObjectPool =poolSet.get(poolName);
}else {
GenericObjectPoolConfig conf =new GenericObjectPoolConfig();
conf.setMaxTotal(maxTotal);
conf.setTestOnBorrow(false);
conf.setTestOnReturn(true);
conf.setTestWhileIdle(true);
conf.setMaxIdle(maxTotal);
conf.setMaxWaitMillis(300);
this.maxTotal = maxTotal;
this.genericObjectPool =new GenericObjectPool(new IntellifObjectPoolFactory(tClass), conf);
}
}
public StringgetPoolName() {
return poolName;
}
public void setPoolName(String poolName) {
this.poolName = poolName;
}
public int getMaxTotal() {
return maxTotal;
}
public void setMaxTotal(int maxTotal) {
this.maxTotal = maxTotal;
}
public GenericObjectPoolgetGenericObjectPool() {
return genericObjectPool;
}
public void setGenericObjectPool(GenericObjectPool genericObjectPool) {
this.genericObjectPool = genericObjectPool;
}
public ClassgettClass() {
return tClass;
}
public void settClass(Class tClass) {
this.tClass = tClass;
}
}
ObjectPool
//从池中获取对象T borrowObject();
//将对象放回池中void returnObject(T obj)
//废弃对象void invalidateObject(T obj)
//添加对象void addObject();
//获取空闲对象个数 int getNumIdle();
//获取活跃对象个数int getNumActive();
//清除池,池可用void clear()
//关闭池,池不可用void close();
通过代理类获取池对象,进行池的对象取用与归还。目前需要手动从池中取数据,再归还,再关闭池。
4.扩展想法
1.实现池对象的自动归还
2.泛型的扩展,实例的复制,活性化对象池。
网友评论