首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 線程獲取返回值的三種模式:共享變量、CountDownLatch、ExecutorService

     編輯:程式設計綜合問答

問題本質

Java Thread.run() 返回值為 void,無法直接返回計算結果。需通過共享內存或 Future 模式獲取異步計算結果。

方案一:final 數組 + CountDownLatch(基礎同步)

適用於簡單單次任務,手動控制等待。

public void test() throws InterruptedException {
    final int[] result = new int[1];
    final CountDownLatch latch = new CountDownLatch(1);

    Thread t = new Thread(() -> {
        // 耗時計算
        result[0] = computeHeavy();
        latch.countDown(); // 釋放等待
    });
    t.start();

    latch.await(); // 阻塞直到 countDown
    System.out.println("Result: " + result[0]);
}

方案二:ExecutorService + Callable + Future(標準庫推薦)

線程池管理,支持超時、取消、異常傳播,生產環境首選。

public void test() throws ExecutionException, InterruptedException {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Callable task = () -> computeHeavy();
    Future future = executor.submit(task);

    // 可做其他事...
    Integer result = future.get(5, TimeUnit.SECONDS); // 支持超時
    System.out.println("Result: " + result);
    executor.shutdown();
}

方案三:CompletableFuture (Java 8+ 異步編程)

鏈式組合、異步回調、多任務編排,現代 Java 首選。

public void test() {
    CompletableFuture.supplyAsync(() -> computeHeavy())
        .thenAccept(result -> System.out.println("Result: " + result))
        .exceptionally(ex -> {
            ex.printStackTrace();
            return null;
        });
    // 主線程繼續執行,異步回調處理結果
}

對比選型指南

維度CountDownLatchFutureCompletableFuture
複雜度低中高
線程管理手動線程池ForkJoinPool/自定義
組合能力無有限強大
異常處理手動get()拋出exceptionally
適用場景簡單同步等待標準異步任務複雜異步流程

避坑指南

  • 共享變量必須 final 或 volatile 保證可見性,基本類型用數組包裝。
  • future.get() 會阻塞調用線程,UI 線程慎用,應在後台線程或配合 thenAccept 使用。
  • 線程池務必 shutdown() 避免資源洩漏,長期運行應用建議單例線程池。

根據業務複雜度選擇同步工具,拒絕在 run() 里寫死邏輯,擁抱現代並發 API。

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