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

Guava ListenableFuture 深度解析:非阻塞異步編程指南

     編輯:Java 相關知識

Guava 並行工具包中的 Future 增強

Google Guava 為 Java 標準庫的 Future 接口提供了強大的擴展,核心在於 ListenableFuture 接口及其配套的 Futures 靜態工具類。這些工具讓開發者能夠以聲明式風格編寫非阻塞異步代碼,避免傳統 Future.get() 造成的線程阻塞。

核心特性:可監聽的 Future

ListenableFuture 繼承自 JDK 的 Future,新增了 addListener(Runnable, Executor) 方法,允許在異步計算完成時自動觸發回調。Guava 進一步封裝了更方便的 Futures.addCallback() 方法,支援成功與失敗兩種回調場景:

Futures.addCallback(listenableFuture, new FutureCallback<Object>() {
    @Override
    public void onSuccess(Object result) {
        System.out.printf("計算成功: %s%n", result);
    }
    @Override
    public void onFailure(Throwable thrown) {
        System.out.printf("計算失敗: %s%n", thrown.getMessage());
    }
}, executor);

Futures 工具類常用靜態方法

  1. transform:對 ListenableFuture 的結果進行轉換,支援同步與異步(AsyncFunction)兩種模式。
  2. allAsList:聚合多個 Future,全部成功才返回結果列表;任一失敗或取消則整體失敗。
  3. successfulAsList:類似 allAsList,但失敗/取消的 Future 在結果列表中以 null 佔位,不拋出異常。
  4. immediateFuture / immediateCancelledFuture:立即創建已完成或已取消的 Future,適用於測試或已知結果場景。
  5. makeChecked:將 ListenableFuture 轉為 CheckedFuture,其 get() 方法拋出受檢異常,便於在業務邏輯中統一異常處理。
  6. JdkFutureAdapters.listenInPoolThread:將 JDK 原生 Future 包裝為 ListenableFuture,實現舊代碼平滑遷移。

實戰範例:組合多個異步任務

@Test
public void testFuturesComposition() throws Exception {
    ListeningExecutorService service = MoreExecutors.listeningDecorator(
        Executors.newFixedThreadPool(10)
    );

    ListenableFuture<Integer> future1 = service.submit(() -> {
        Thread.sleep(1000);
        System.out.println("Task 1 done");
        return 1;
    });

    ListenableFuture<Integer> future2 = service.submit(() -> {
        Thread.sleep(1000);
        System.out.println("Task 2 done");
        return 2;
    });

    // 等待兩個任務全部完成
    ListenableFuture<List<Integer>> all = Futures.allAsList(future1, future2);

    // 異步轉換結果
    ListenableFuture<String> transformed = Futures.transformAsync(all, results -> 
        Futures.immediateFuture(String.format("成功完成 %d 個任務", results.size()))
    , service);

    // 註冊最終回調
    Futures.addCallback(transformed, new FutureCallback<String>() {
        @Override
        public void onSuccess(String result) {
            System.out.println("最終結果: " + result);
        }
        @Override
        public void onFailure(Throwable t) {
            System.err.println("流程失敗: " + t.getMessage());
        }
    }, service);

    // 阻塞等待演示(實際生產中應避免)
    System.out.println(transformed.get());
}

最佳實踐建議

  • 優先使用 ListeningExecutorService 提交任務,直接獲得 ListenableFuture。
  • 善用 transformAsync 進行異步鏈式調用,避免阻塞線程。
  • 根據業務容錯需求選擇 allAsList(強一致性)或 successfulAsList(部分容錯)。
  • 記得關閉 ListeningExecutorService 釋放線程資源。

官方文檔參考:Guava ListenableFuture Explained

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