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

Java 併發核心:Runnable、Callable、Future、FutureTask 深度對比與實戰

     編輯:Java 相關知識

四大核心介面/類關係圖

Runnable (void run())
    ↑
FutureTask ──────────────→ implements RunnableFuture
    ↑                          ↑
    │                    extends Runnable, Future
    │
Callable (V call() throws Exception)
    │
    └─→ Executors.callable(Runnable, result) 轉換

核心差異速查

介面/類方法返回值拋出異常用途
Runnablerun()void不可拋受檢異常簡單任務、無回傳
Callable<V>call()V可拋 Exception有回傳、可拋異常任務
Future<V>get()/cancel()/isDone()V—任務結果控制介面
FutureTask<V>run() + get()V—Runnable+Future 合體、可包裝兩者

FutureTask 核心價值

  • 實作 RunnableFuture<V>:既是 Runnable 可提交執行緒池,也是 Future 可獲取結果
  • 構造函數支援包裝 Callable 或 Runnable(內部轉為 Callable)
  • get() 阻塞等待結果,適合「提交任務→做其他事→取結果」模式

完整實戰範例

public class FutureTest {
    // 耗時運算:遞迴費波那契
    static int fibc(int n) {
        if (n <= 1) return n;
        return fibc(n-1) + fibc(n-2);
    }

    // 1. Runnable + ExecutorService
    static void testRunnable() {
        ExecutorService es = Executors.newCachedThreadPool();
        Future<String> f = es.submit(new Task()); // Task implements Runnable
        System.out.println(f.get()); // 印出 null (Runnable 無回傳)
        es.shutdown();
    }

    // 2. Callable + ExecutorService
    static void testCallable() {
        ExecutorService es = Executors.newCachedThreadPool();
        Future<Integer> f = es.submit(new Task2()); // Task2 implements Callable
        System.out.println(f.get()); // 印出 832040
        es.shutdown();
    }

    // 3. FutureTask + ExecutorService (推薦)
    static void testFutureTask() {
        ExecutorService es = Executors.newCachedThreadPool();
        FutureTask<Integer> ft = new FutureTask<>(new Task2());
        es.submit(ft);
        System.out.println(ft.get()); // 直接取結果
        es.shutdown();
    }

    // 4. FutureTask 包裝 Runnable + 指定回傳值
    static void testFutureTask2() {
        ExecutorService es = Executors.newCachedThreadPool();
        FutureTask<Integer> ft = new FutureTask<>(
            () -> System.out.println("run"), // Runnable
            fibc(30)                         // 回傳值
        );
        es.submit(ft);
        System.out.println(ft.get());
        es.shutdown();
    }
}

關鍵設計細節

RunnableAdapter 適配器

static final class RunnableAdapter<T> implements Callable<T> {
    final Runnable task;
    final T result;
    public T call() { task.run(); return result; }
}

Executors.callable(runnable, result) 將 Runnable 包裝為 Callable,執行完 run() 返回指定 result。

最佳實踐建議

  1. **無回傳、無異常** → 直接用 Runnable + ExecutorService
  2. **需回傳值或拋異常** → 用 Callable + ExecutorService.submit()
  3. **需手動控制任務執行時機、或非執行緒池環境** → 用 FutureTask 直接 new Thread(ft).start() 或提交池中
  4. **批量提交、需取消、超時控制** → 善用 Future.get(timeout, unit)、cancel()
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved