美文网首页
创建型模式——对象池模式

创建型模式——对象池模式

作者: Doooook | 来源:发表于2020-08-17 21:45 被阅读0次

    对象的实例化是最耗费性能的操作之一,这在过去是个大问题,现在不用再过分关注它。但当我们处理封装外部资源的对象(例如数据库连接)时,对象的创建操作则会耗费很多资源。
    解决方案是重用共享这些创建成本高昂的对象,这称为对象池模式

    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();
        }
    

    参考:https://www.jianshu.com/p/38c5bccf892f

    相关文章

      网友评论

          本文标题:创建型模式——对象池模式

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