目录
Okhttp3使用及解析:https://mp.csdn.net/postedit/83339916
okhttp系统拦截器:https://mp.csdn.net/postedit/83536609
Okhttp的连接池ConnectionPool:https://mp.csdn.net/postedit/83650740
Okhttp将客户端和服务端之间通信的链接抽象成Connection类,而ConnectionPool就是管理这些链接的复用而出现的,作用就是在一定时间内可以复用Connection。
下面分析源码:
1.get()方法
@Nullable
RealConnection get(Address address, StreamAllocation streamAllocation, Route route) {
assert (Thread.holdsLock(this));
//遍历连接池connections
for (RealConnection connection : connections) {
//isEligible判断是否可用
if (connection.isEligible(address, route)) {
//acquire获取连接池
streamAllocation.acquire(connection, true);
return connection;
}
}
return null;
}
看看acquire():
public void acquire(RealConnection connection, boolean reportedAcquired) {
assert (Thread.holdsLock(connectionPool));
if (this.connection != null) throw new IllegalStateException();
//将连接池中获取的RealConnection赋值
this.connection = connection;
this.reportedAcquired = reportedAcquired;
//将弱引用的StreamAllocation存入集合allocations
connection.allocations.add(new StreamAllocationReference(this, callStackTrace));
}
集合allocations存储的多个StreamAllocation,方便后期通过size大小的判断一个网络链接的负载量是否超过最大值。
总结:每次的http请求会在重定向拦截器中创建StreamAllocation,且StreamAllocation的弱引用会被添加至泛型为RealConnection的集合中,后面可通过集合大小判断链接是否超过负载。同时,也提供在一定时间内连接池复用链接。
2.put()
void put(RealConnection connection) {
assert (Thread.holdsLock(this));
//线程池异步回收connection
if (!cleanupRunning) {
cleanupRunning = true;
executor.execute(cleanupRunnable);
}
//connection存入队列
connections.add(connection);
}
题外话:看看cleanupRunnable回收的流程:
private final Runnable cleanupRunnable = new Runnable() {
@Override public void run() {
while (true) {
//计算下一次清理的时间
//gc的标记算法,存StreamAllocation弱引用的集合,遍历发现为空,则remove
long waitNanos = cleanup(System.nanoTime());
if (waitNanos == -1) return;
if (waitNanos > 0) {
long waitMillis = waitNanos / 1000000L;
waitNanos -= (waitMillis * 1000000L);
synchronized (ConnectionPool.this) {
try {
//等待时间,去执行下次清理
ConnectionPool.this.wait(waitMillis, (int) waitNanos);
} catch (InterruptedException ignored) {
}}}}}};