对象池

作者: 升空的焰火 | 来源:发表于2018-11-15 15:43 被阅读0次

    一、对象池概述:

    对于那些实例化开销比较大,并且生命周期比较短的对象,我们可以通过池就行管理。所谓池,就相当于一个仓库,里面的东西是有借有还的。这样可以控制池内对象的数量,开销,并且一个对象实例可以重复使用。

    二、自定义连接池:

    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.泛型的扩展,实例的复制,活性化对象池。

    相关文章

      网友评论

          本文标题:对象池

          本文链接:https://www.haomeiwen.com/subject/fvsefqtx.html