OKhttp的理解-RealConnectionPool
Posted 杨希锋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OKhttp的理解-RealConnectionPool相关的知识,希望对你有一定的参考价值。
RealConnectionPool
构造方案的参数:
maxIdleConnections: 最大连接数,默认为5。
keepAliveDuration: 存活时间,默认为5分钟。
public RealConnectionPool(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) {
this.maxIdleConnections = maxIdleConnections; //默认为5
this.keepAliveDurationNs = timeUnit.toNanos(keepAliveDuration); //默认为5分钟
// Put a floor on the keep alive duration, otherwise cleanup will spin loop.
if (keepAliveDuration <= 0) {
throw new IllegalArgumentException("keepAliveDuration <= 0: " + keepAliveDuration);
}
}
清理逻辑
采用一个线程池,核心线程数为0、最大线程数为Inter.MAX_VALUE, 空闲线程存活时间为60秒,等待队列为无缓冲队列(SynchronousQueue),即同一时间只能有一个任务在执行。清除流程为:
遍历connections队列,找到空闲最长时间的连接,如果最长空闲时间超过5分钟、或者空闲连接数量大于5,则从队列中删除该连接并关闭socket。
public final class RealConnectionPool {
...
/**
* @param now: 当前时间戳
* @return: 分几种情况:
* > 0:距离下次清除的时间间隔;
* = 0: 已成功清除了最长空闲时间的连接;
* -1: connections队列为空,无空闲或正在使用的连接。
*/
long cleanup(long now) {
int inUseConnectionCount = 0;
int idleConnectionCount = 0;
RealConnection longestIdleConnection = null;
long longestIdleDurationNs = Long.MIN_VALUE;
// Find either a connection to evict, or the time that the next eviction is due.
synchronized (this) {
for (Iterator<RealConnection> i = connections.iterator(); i.hasNext(); ) {
RealConnection connection = i.next();
// If the connection is in use, keep searching.
if (pruneAndGetAllocationCount(connection, now) > 0) {
inUseConnectionCount++;
continue;
}
idleConnectionCount++;
// If the connection is ready to be evicted, we\'re done.
long idleDurationNs = now - connection.idleAtNanos;
if (idleDurationNs > longestIdleDurationNs) {
longestIdleDurationNs = idleDurationNs;
longestIdleConnection = connection;
}
}
if (longestIdleDurationNs >= this.keepAliveDurationNs
|| idleConnectionCount > this.maxIdleConnections) {
// We\'ve found a connection to evict. Remove it from the list, then close it below (outside
// of the synchronized block).
connections.remove(longestIdleConnection);
} else if (idleConnectionCount > 0) {
// A connection will be ready to evict soon.
return keepAliveDurationNs - longestIdleDurationNs;
} else if (inUseConnectionCount > 0) {
// All connections are in use. It\'ll be at least the keep alive duration \'til we run again.
return keepAliveDurationNs;
} else {
// No connections, idle or in use.
cleanupRunning = false;
return -1;
}
}
closeQuietly(longestIdleConnection.socket());
// Cleanup again immediately.
return 0;
}
}
以上是关于OKhttp的理解-RealConnectionPool的主要内容,如果未能解决你的问题,请参考以下文章
三、深入理解OkHttp:连接处理-ConnectIntercepter