作者:vivo 互联网服务器团队-Huang Xiaoqun
一、前言
二、commons-pool2池化技术剖析
/**
*向对象池中增加对象实例
*/
void addObject() throws Exception, IllegalStateException,
UnsupportedOperationException;
/**
* 从对象池中获取对象
*/
T borrowObject() throws Exception, NoSuchElementException,
IllegalStateException;
/**
* 失效非法的对象
*/
void invalidateObject(T obj) throws Exception;
/**
* 释放对象至对象池
*/
void returnObject(T obj) throws Exception;
public GenericObjectPool(final PooledObjectFactory<T> factory) {
this(factory, new GenericObjectPoolConfig<T>());
}
public GenericObjectPool(final PooledObjectFactory<T> factory,
final GenericObjectPoolConfig<T> config) {
super(config, ONAME_BASE, config.getJmxNamePrefix());
if (factory == null) {
jmxUnregister(); // tidy up
throw new IllegalArgumentException("factory may not be null");
}
this.factory = factory;
idleObjects = new LinkedBlockingDeque<>(config.getFairness());
setConfig(config);
}
public GenericObjectPool(final PooledObjectFactory<T> factory,
final GenericObjectPoolConfig<T> config, final AbandonedConfig abandonedConfig) {
this(factory, config);
setAbandonedConfig(abandonedConfig);
}
/**
* 向对象池中增加对象,一般在预加载的时候会使用该功能
*/
public void addObject() throws Exception {
assertOpen();
if (factory == null) {
throw new IllegalStateException(
"Cannot add objects without a factory.");
}
final PooledObject<T> p = create();
addIdleObject(p);
}
final PooledObject<T> p;
try {
p = factory.makeObject();
if (getTestOnCreate() && !factory.validateObject(p)) {
createCount.decrementAndGet();
return null;
}
} catch (final Throwable e) {
createCount.decrementAndGet();
throw e;
} finally {
synchronized (makeObjectCountLock) {
makeObjectCount--;
makeObjectCountLock.notifyAll();
}
}
/**
* 第一个节点
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
private transient Node<E> first; // @GuardedBy("lock")
/**
* 最后一个节点
* Invariant: (first == null && last == null) ||
* (last.next == null && last.item != null)
*/
private transient Node<E> last; // @GuardedBy("lock")
/** 当前队列长度 */
private transient int count; // @GuardedBy("lock")
/** 队列最大容量 */
private final int capacity;
/** 主锁 */
private final InterruptibleReentrantLock lock;
/** 队列是否为空状态锁 */
private final Condition notEmpty;
/** 队列是否满状态锁 */
private final Condition notFull;
public boolean offerFirst(final E e, final long timeout, final TimeUnit unit)
throws InterruptedException {
Objects.requireNonNull(e, "e");
long nanos = unit.toNanos(timeout);
lock.lockInterruptibly();
try {
while (!linkFirst(e)) {
if (nanos <= 0) {
return false;
}
nanos = notFull.awaitNanos(nanos);
}
return true;
} finally {
lock.unlock();
}
}
public E takeFirst() throws InterruptedException {
lock.lock();
try {
E x;
while ( (x = unlinkFirst()) == null) {
notEmpty.await();
}
return x;
} finally {
lock.unlock();
}
}
private boolean linkLast(final E e) {
// assert lock.isHeldByCurrentThread();
if (count >= capacity) {
return false;
}
final Node<E> l = last;
final Node<E> x = new Node<>(e, l, null);
last = x;
if (first == null) {
first = x;
} else {
l.next = x;
}
++count;
notEmpty.signal();
return true;
}
//1、尝试从双端队列中获取对象,pollFirst方法是非阻塞方法
p = idleObjects.pollFirst();
if (p == null) {
p = create();
if (p != null) {
create = true;
}
}
if (blockWhenExhausted) {
if (p == null) {
if (borrowMaxWaitMillis < 0) {
//2、没有设置最大阻塞等待时间,则无限等待
p = idleObjects.takeFirst();
} else {
//3、设置最大等待时间了,则阻塞等待指定的时间
p = idleObjects.pollFirst(borrowMaxWaitMillis,
TimeUnit.MILLISECONDS);
}
}
}
//修改对象状态
if (!p.allocate()) {
p = null;
}
if (p != null) {
try {
//初始化对象
factory.activateObject(p);
} catch (final Exception e) {
try {
destroy(p, DestroyMode.NORMAL);
} catch (final Exception e1) {
}
}
if (p != null && getTestOnBorrow()) {
boolean validate = false;
Throwable validationThrowable = null;
try {
//验证对象的可用性状态
validate = factory.validateObject(p);
} catch (final Throwable t) {
PoolUtils.checkRethrow(t);
validationThrowable = t;
}
//对象不可用,验证失败,则进行destroy
if (!validate) {
try {
destroy(p, DestroyMode.NORMAL);
destroyedByBorrowValidationCount.incrementAndGet();
} catch (final Exception e) {
// Ignore - validation failure is more important
}
}
}
}
public class PoolState {
protected final List<PooledObject> idleObjects = new ArrayList<>();
protected final List<PooledObject> activeObjects = new ArrayList<>();
//...
}
//根据配置确定是否要为标签删除调用removeAbandoned方法
final AbandonedConfig ac = this.abandonedConfig;
if (ac != null && ac.getRemoveAbandonedOnBorrow() && (getNumIdle() < 2) && (getNumActive() > getMaxTotal() - 3) ) {
removeAbandoned(ac);
}
public final void setTimeBetweenEvictionRunsMillis(
final long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
startEvictor(timeBetweenEvictionRunsMillis);
}
final void startEvictor(final long delay) {
synchronized (evictionLock) {
EvictionTimer.cancel(evictor, evictorShutdownTimeoutMillis, TimeUnit.MILLISECONDS);
evictor = null;
evictionIterator = null;
//如果delay<=0则不会开启定时清理任务
if (delay > 0) {
evictor = new Evictor();
EvictionTimer.schedule(evictor, delay, delay);
}
}
}
boolean evict;
try {
evict = evictionPolicy.evict(evictionConfig, underTest,
idleObjects.size());
} catch (final Throwable t) {
// Slightly convoluted as SwallowedExceptionListener
// uses Exception rather than Throwable
PoolUtils.checkRethrow(t);
swallowException(new Exception(t));
// Don't evict on error conditions
evict = false;
}
if (evict) {
// 如果可以被回收则直接调用destroy进行回收
destroy(underTest);
destroyedByEvictorCount.incrementAndGet();
}
boolean active = false;
try {
// 调用activateObject激活该空闲对象,本质上不是为了激活,
// 而是通过这个方法可以判定是否还存活,这一步里面可能会有一些资源的开辟行为。
factory.activateObject(underTest);
active = true;
} catch (final Exception e) {
// 如果激活的时候,发生了异常,就说明该空闲对象已经失联了。
// 调用destroy方法销毁underTest
destroy(underTest);
destroyedByEvictorCount.incrementAndGet();
}
if (active) {
// 再通过进行validateObject校验有效性
if (!factory.validateObject(underTest)) {
// 如果校验失败,说明对象已经不可用了
destroy(underTest);
destroyedByEvictorCount.incrementAndGet();
} else {
try {
/*
*因为校验还激活了空闲对象,分配了额外的资源,那么就通过passivateObject把在activateObject中开辟的资源释放掉。
*/
factory.passivateObject(underTest);
} catch (final Exception e) {
// 如果passivateObject失败,也可以说明underTest这个空闲对象不可用了
destroy(underTest);
destroyedByEvictorCount.incrementAndGet();
}
}
}
三、写在最后
END
猜你喜欢
vivo互联网技术
vivo移动互联网是基于vivo 智能手机所建立的完整移动互联网生态圈,围绕vivo大数据运营,打造包括应用、游戏、资讯、品牌、电商、内容、金融、搜索的全方位服务生态,满足海量用户的多样化需求。
点一下,代码无 Bug