首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java HttpClient 非同步請求完整實作:FutureCallback、CountDownLatch 與資源管理

     編輯:Java 相關知識

依賴

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpasyncclient</artifactId>
  <version>4.1.4</version>  <!-- 4.x 版本 -->
</dependency>et

註:HttpAsyncClient 5.x 已整合至 httpclient5,API 不同,本文針對 4.x 經典版本。

完整範例:並發 GET 多個網址

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.nio.client.DefaultHttpAsyncClient;
import org.apache.http.nio.client.HttpAsyncClient;
import org.apache.http.nio.concurrent.FutureCallback;
import org.apache.http.nio.reactor.IOReactorException;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class AsyncHttpDemo {
    public static void main(String[] args) throws IOReactorException, InterruptedException {
        // 1. 建立非同步客戶端(內部使用 NIO Reactor 執行緒池)
        HttpAsyncClient client = new DefaultHttpAsyncClient();
        client.start();  // 必須啟動

        // 2. 準備請求
        HttpGet[] requests = {
            new HttpGet("https://www.apache.org/"),
            new HttpGet("https://www.verisign.com/"),
            new HttpGet("https://www.google.com/")
        };

        // 3. CountDownLatch 等待所有回調完成
        CountDownLatch latch = new CountDownLatch(requests.length);

        // 4. 發送請求並註冊回調
        for (HttpGet req : requests) {
            client.execute(req, new FutureCallback() {
                @Override
                public void completed(HttpResponse response) {
                    System.out.println(req.getRequestLine() + " -> " + response.getStatusLine());
                    latch.countDown();
                }
                @Override
                public void failed(Exception ex) {
                    ex.printStackTrace();
                    latch.countDown();
                }
                @Override
                public void cancelled() {
                    System.out.println(req.getRequestLine() + " cancelled");
                    latch.countDown();
                }
            });
        }

        System.out.println("Requests dispatched, waiting...");

        // 5. 等待完成(設定超時避免永久阻塞)
        boolean finished = latch.await(30, TimeUnit.SECONDS);
        if (!finished) System.err.println("Timeout waiting for responses");

        // 6. 關閉客戶端(釋放 NIO 執行緒、連線池)
        client.shutdown();
        System.out.println("Done");
    }
}

關鍵類別與執行流程

類別角色
DefaultHttpAsyncClient非同步 HTTP 客戶端,內部持有 IOReactor (NIO 事件迴路)
HttpAsyncClient.execute()非阻塞發送請求,立即返回,完成時回調 FutureCallback
FutureCallback三種狀態:completed/failed/cancelled
CountDownLatch主執行緒等待所有非同步任務完成的同步器

生產環境強化建議

  1. 連線池配置:PoolingNHttpClientConnectionManager 限制最大連線數、每路由連線數
  2. 超時控制:RequestConfig 設定連線/讀取/寫入超時
  3. 重試機制:在 failed() 中判斷錯誤類型(網路抖動 vs 4xx),決定是否重試
  4. 背壓/限流:使用 Semaphore 或 RateLimiter (Guava/Resilience4j) 控制併發發送速率
  5. 優雅關閉:JVM 關閉鉤子中呼叫 client.shutdown(),等待進行中請求完成
  6. 遷移至 HttpClient 5.x:CloseableHttpAsyncClient + FutureCallback,API 更現代、支援 HTTP/2

HttpClient 5.x 遷移提示

// 5.x 風格
CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
client.start();
client.execute(new SimpleHttpRequest("GET", "https://example.com"), 
    new FutureCallback() { ... });
// 關閉
client.close(CloseMode.GRACEFUL);

總結

HttpAsyncClient 4.x 以 FutureCallback + CountDownLatch 實現簡潔的非同步並發請求。核心要點:啟動 client、註冊回調、Latch 等待、優雅關閉。新專案建議直接使用 HttpClient 5.x 或 Java 11+ HttpClient (java.net.http) 獲得原生非同步支援與 HTTP/2 能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved