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

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

作者: 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

相关文章

  • 对象池模式(Pool)

    1.5.1. 目的 对象池模式是一种提前准备了一组已经初始化了的对象『池』而不是按需创建或者销毁的创建型设计模式。...

  • 单例模式

    单例模式是创建型设计模式的一种。针对全局仅需一个对象的场景,如线程池、全局缓存、window 对象等

  • 设计模式

    1.设计模式的分类 ⑴创建型 创建型(Creational)模式:将对象的部分创建工作延迟到子类或者其他对象,从而...

  • 对象池模式(Object Pool Pattern)

    本文节选自《设计模式就该这样学》 1对象池模式的定义 对象池模式(Object Pool Pattern),是创建...

  • 设计模式之工厂模式

    设计模式中主要分为三大类:创建型、结构型、行为型 工厂模式属于创建型,顾名思义,创建型模式关注对象的创建过程,它将...

  • 对象池模式的使用

    一、模式介绍 对象池模式可以归类为创建型模式,是预先创建若干对象然后保存到内存对象池中,等到程序需要使用对象的时候...

  • 23种模式 - 总结

    创建型设计模式 创建型设计模式主要解决对象的创建问题,封装复杂的创建过程,解耦对象的创建代码和使用代码。包括:单例...

  • 三、原型模式

    原型模式用于创建重复对象的同时保持性能,该模式属于创建型设计模式,是创建对象的最佳实现方式。 为什么要使用原型模式...

  • 23种设计模式学习总结

    创建型设计模式 主要解决对象的创建问题,封装复杂的创建过程,解耦对象的创建代码合使用代码。 单例模式 单例模式用来...

  • 建造者设计模式-Builder design pattern

    建造者设计模式是创建型设计模式的一种。创建型设计模式处理对象创建的问题。 建造者设计模式,用来构建需要经过若干个建...

网友评论

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

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