commons pool2 的org.apache.commons.pool2.impl包下提供了一个对象池的具体实现GenericObjectPool。
类内部使用一个ConcurrentHashmap存储所有的objects:
private final Map<IdentityWrapper<T>, PooledObject<T>> allObjects =
new ConcurrentHashMap<IdentityWrapper<T>, PooledObject<T>>();
其中使用了一个包裹类IdentityWrapper作为map的key,该类是GenericObjectPool的一个static类:
static class IdentityWrapper<T> {
/** Wrapped object */
private final T instance;
...
@Override
public int hashCode() {
return System.identityHashCode(instance);
}
@Override
@SuppressWarnings("rawtypes")
public boolean equals(Object other) {
return ((IdentityWrapper) other).instance == instance;
}
...
之所以用一个类又把对象包裹了一层来作为map的key,是防止GenericObjectPool中存放的对象没有很好的实现其hashCode方法,有可能会使map产生大量hash冲突,降低map存取元素的效率。
用一个阻塞队列来保存idle空闲对象:
private final LinkedBlockingDeque<PooledObject<T>> idleObjects;
阻塞队列在GenericObjectPool构造方法中初始化:
public GenericObjectPool(PooledObjectFactory<T> factory,
GenericObjectPoolConfig config) {
...
idleObjects = new LinkedBlockingDeque<PooledObject<T>>(config.getFairness());
...
从源码中可以看出,可以将阻塞队列配置成非公平锁模式或者公平锁模式。