高性能对象池:对象复用的艺术🏊

22 阅读1分钟

创建对象很贵?那就复用!对象池让你的应用飞起来!

一、为什么需要对象池?

问题:频繁创建销毁对象

// ❌ 每次都new
for (int i = 0; i < 1000000; i++) {
    Connection conn = new Connection();  // 创建开销大
    conn.query();
    conn.close();  // GC压力大
}

解决:对象池复用

// ✅ 从池中取
for (int i = 0; i < 1000000; i++) {
    Connection conn = pool.borrow();  // 复用
    conn.query();
    pool.return(conn);  // 归还
}

二、简单对象池实现

public class SimpleObjectPool<T> {
    
    private final Queue<T> pool;
    private final int maxSize;
    private final Supplier<T> factory;
    
    public SimpleObjectPool(int maxSize, Supplier<T> factory) {
        this.maxSize = maxSize;
        this.factory = factory;
        this.pool = new ConcurrentLinkedQueue<>();
        
        // 预热
        for (int i = 0; i < maxSize / 2; i++) {
            pool.offer(factory.get());
        }
    }
    
    public T borrow() {
        T obj = pool.poll();
        return obj != null ? obj : factory.get();
    }
    
    public void returnObject(T obj) {
        if (pool.size() < maxSize) {
            pool.offer(obj);
        }
    }
}

三、Apache Commons Pool

GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(100);
config.setMaxIdle(50);
config.setMinIdle(10);

ObjectPool<Connection> pool = new GenericObjectPool<>(
    new ConnectionFactory(), config
);

// 使用
Connection conn = pool.borrowObject();
try {
    conn.query();
} finally {
    pool.returnObject(conn);
}

四、使用场景

  • 数据库连接池:HikariCP、Druid
  • 线程池:ThreadPoolExecutor
  • ByteBuffer池:Netty
  • 对象池:Apache Commons Pool

下一篇→ 并行流的陷阱🌊