对象池模式

对象池(英语:object pool pattern)是一种设计模式。一个对象池包含一组已经初始化过且可以使用的对象,而可以在有需求时创建和销毁对象。池的用户可以从池子中取得对象,对其进行操作处理,并在不需要时归还给池子而非直接销毁它。这是一种特殊的工厂对象。

若初始化、实例化的代价高,且有需求需要经常实例化,但每次实例化的数量较少的情况下,使用对象池可以获得显著的效能提升。从池子中取得对象的时间是可预测的,但新建一个实例所需的时间是不确定。

示例


import java.util.HashMap;
 
public abstract class ObjectPool<T> {
    // 容器, 容纳对象
    private HashMap<T, ObjectStatus> pool = new HashMap<T, ObjectStatus>();
 
    // 初始化时创建对象, 并放入到池中
    public ObjectPool() {
        pool.put(create(), new ObjectStatus());
    }
 
    // 从Hashtable中取出空闲元素
    public synchronized T checkOut() {
        // 这是最简单的策略
        for (T t : pool.keySet()) {
            if (pool.get(t).validate()) {
                pool.get(t).setUsing();
                return t;
            }
        }
        return null;
    }
 
    // 归还对象public
    public synchronized void checkIn(T t) {
        pool.get(t).setFree();
    }
 
    class ObjectStatus {
        // 占用
        public void setUsing() {
        }
 
        // 释放
        public void setFree() {
            // 注意: 若T是有状态, 则需要回归到初始化状态
        }
 
        // 检查是否可用
        public boolean validate() {
            return false;
        }
    }
 
    // 创建池化对象
    public abstract T create();
}

优缺点

优点

减少初始化对象的开销,从而提高系统的整体性能。

缺点

增加了代码的复杂度。

使用场景

  1. 线程池
  2. 连接池

对象池 vs 享元模式

对象池着重于对象的复用上,池内的每个对象都是可替换的,从池中获得对象 A 或者对象 B 对客户端来说是一样的,它主要是为了解决复用的问题,例如线程池。而 享元模式 主要解决对象的共享问题,如何建立多个可共享的细粒度的对象则是其关注重点。

参考文献

维基百科
CSDN