美文网首页轻巧
对象池模式的使用

对象池模式的使用

作者: 文景大大 | 来源:发表于2022-07-09 22:07 被阅读0次

一、模式介绍

对象池模式可以归类为创建型模式,是预先创建若干对象然后保存到内存对象池中,等到程序需要使用对象的时候,直接从对象池中获取已经创建好的对象使用即可,免去了新建对象的巨大开销,节约的时间。同时,等到对象被使用完了,可以将其再次返回对象池中。

通常,在资源比较受限、对象创建销毁成本过高的时候可以考虑使用对象池模式。一般而言,对象池模式包含如下几种角色:

  • 抽象对象,定义对象池中对象的行为;
  • 具体对象,实现对象池中对象的行为;
  • 对象池,持有对象并提供获取和返还等操作;

下面是对象池模式的通用实现代码:

public interface IPoolObject {
    void operation();
}
@Slf4j
public class ConcretePoolObject implements IPoolObject{
    @Override
    public void operation() {
        log.info("ConcretePoolObject operation!!!");
    }
}
@Slf4j
public class ObjectPool {
    /**
     * 最小维持的对象数量
     */
    private int minCount;
    /**
     * 最大维持的对象数量
     */
    private int maxCount;
    /**
     * 需要线程安全
     * 空闲中的对象池
     */
    private Vector<IPoolObject> idleObjects;
    /**
     * 已被使用中的对象池
     */
    private Vector<IPoolObject> busyObjects;
    /**
     * 递增步长
     */
    public static final Integer INCREASE_STEP = 10;

    public ObjectPool(int minCount, int maxCount){
        this.minCount = minCount;
        this.maxCount = maxCount;
        this.idleObjects = new Vector<IPoolObject>();
        this.busyObjects = new Vector<IPoolObject>();
        // 初始只实例化最小数量个空闲对象
        this.resizeIdleObjects(minCount);
    }

    /**
     * 重置空闲池
     * @param count 需要添加到空闲池中的对象个数
     */
    private void resizeIdleObjects(int count){
        for(int i=0;i<count;i++){
            idleObjects.add(new ConcretePoolObject());
        }
    }

    /**
     * 归还对象
     * @param object
     */
    public void returnObject(IPoolObject object){
        idleObjects.add(object);
        if(busyObjects.contains(object)){
            busyObjects.remove(object);
        }
    }

    /**
     * 从空闲池中取出一个对象
     * @return
     */
    public IPoolObject getObject() throws Exception {
        IPoolObject poolObject = null;
        if(idleObjects.size() > 0){
            // 空闲池中尚有对象可以使用
            poolObject = idleObjects.get(0);
            idleObjects.remove(poolObject);
            busyObjects.add(poolObject);
        } else {
            // 空闲池中已无可用对象
            if(idleObjects.size() >= maxCount){
                log.error("对象池中对象已达上限,无法再扩容!");
                throw new Exception("对象池中对象已达上限,无法再扩容!");
            }
            // 空闲池进行扩容
            int diffCount = maxCount - minCount;
            resizeIdleObjects(diffCount > INCREASE_STEP ? INCREASE_STEP : diffCount);
            poolObject = getObject();
        }
        return poolObject;
    }
}
public class Main {
    public static void main(String[] args) {
        ObjectPool pool = new ObjectPool(3,8);
        IPoolObject object = null;
        try {
            object = pool.getObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        object.operation();
    }
}

二、使用案例

  • 数据库连接池
  • 线程池

三、模式总结

总的来说,对象池模式更像是单例模式和享元模式的混合体,对象池是单例的,对象池中对象则是共享的。

3.1 优点

  • 省去创建和销毁对象需要的资源和时间开销;

3.2 缺点

  • 并发场景下的处理比较复杂;
  • 伸缩性问题会给对象池带来瓶颈;
  • 很难合理设定对象池的大小,够用和浪费之间的平衡难以掌控;

相关文章

  • 对象池模式的使用

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

  • 【设计模式】之对象池模式--JDBC连接池实现案例

    对象池设计模式 对象池设计模式的目标 对象池可以显著提高性能,在那些初始化一个类实例的代价比较高、但是使用频率比较...

  • 2.6 结构型-享元模式

    使用场景:细粒度共享对象的池化。String常量池,线程池等都是享元模式的应用。 组成要素: Flyweight:...

  • 享元模式

    Android进阶之设计模式 享元模式 定义: 使用共享对象有效地支持大量细粒度的对象. 享元模式是池技术的重要实...

  • Laya_2D示例项目使用对象池预制体的创建、位置设置和添加到父

    //使用对象池创建盒子 1.对象池的使用 对象池创建箱子 let box = Laya.Pool.getI...

  • 内存优化

    对象创建,回收和内存习惯处理 线程处理 使用单例模式 对象池的概念多线程 缓存处理,多使用软引用和弱引用,避免使用...

  • 设计模式之——享元模式

    1 享元模式的定义 享元模式:使用共享对象可有效地支持大量细粒度的对象。享元模式是池技术的重要实现方式。享元模式的...

  • 对象池模式(Object Pool Pattern)

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

  • 《设计模式》享元模式

    基本介绍 定义 使用共享对象可有效地支持大量的细粒度的对象. 介绍 享元模式属于结构型模式。 享元模式是池技术的重...

  • 每日Android源码设计模式之-21、享元模式

    享元模式英文是Flyweight,轻量级的意思。他是对象池的一种实现,由于使用了对象池,大大节约了内存和垃圾回收的...

网友评论

    本文标题:对象池模式的使用

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