可以看到线程阻塞在AbstractConnPool类getPoolEntryBlocking⽅法中。
private E getPoolEntryBlocking(
final T route, final Object state,
final long timeout, final TimeUnit timeUnit,
final Future<E> future) throws IOException, InterruptedException, TimeoutException {        Date deadline = null;
Date deadline = null;
if (timeout > 0) {
deadline = new Date (System.currentTimeMillis() + Millis(timeout));
}
this.lock.lock();
try {
//根据route获取route对应的连接池
final RouteSpecificPool<T, C, E> pool = getPool(route);
E entry;
for (;;) {
Asserts.check(!this.isShutDown, "Connection pool shut down");
for (;;) {
//获取可⽤的连接
entry = Free(state);
if (entry == null) {
break;
}
/
/ 判断连接是否过期,如过期则关闭并从可⽤连接集合中删除
if (entry.isExpired(System.currentTimeMillis())) {
entry.close();
}
if (entry.isClosed()) {
ve(entry);
pool.free(entry, false);
} else {
break;
}
}
/
/ 如果从连接池中获取到可⽤连接,更新可⽤连接和待释放连接集合
if (entry != null) {
ve(entry);
this.leased.add(entry);
onReuse(entry);
return entry;
}
// 如果没有可⽤连接,则创建新连接
final int maxPerRoute = getMax(route);
// 创建新连接之前,检查是否超过每个route连接池⼤⼩,如果超过,则删除可⽤连接集合相应数量的连接(从总的可⽤连接集合和每个route的可⽤连接集合中删除)                final int excess = Math.max(0, AllocatedCount() + 1 - maxPerRoute);
if (excess > 0) {
for (int i = 0; i < excess; i++) {
final E lastUsed = LastUsed();
if (lastUsed == null) {
break;
抽象类的使用}
lastUsed.close();
ve(lastUsed);
}
}
if (AllocatedCount() < maxPerRoute) {
//⽐较总的可⽤连接数量与总的可⽤连接集合⼤⼩,释放多余的连接资源
final int totalUsed = this.leased.size();
final int freeCapacity = Math.max(this.maxTotal - totalUsed, 0);
if (freeCapacity > 0) {
final int totalAvailable = this.available.size();
if (totalAvailable > freeCapacity - 1) {
if (!this.available.isEmpty()) {
final E lastUsed = veLast();
lastUsed.close();
final RouteSpecificPool<T, C, E> otherpool = Route());
}
}
// 真正创建连接的地⽅
final C conn = ate(route);
entry = pool.add(conn);
this.leased.add(entry);
return entry;
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。