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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章