首页 > Web开发 > 详细

OKhttp的理解-RealConnectionPool

时间:2021-05-30 20:21:21      阅读:18      评论:0      收藏:0      [点我收藏+]

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

原文:https://www.cnblogs.com/xifengcoder/p/14828293.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!