Okhttp的连接池ConnectionPool(三)

目录

1.get()方法

2.put()


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) {
            }}}}}};

 

 

你可能感兴趣的:(android源码分析)