Runnable (void run())
↑
FutureTask ──────────────→ implements RunnableFuture
↑ ↑
│ extends Runnable, Future
│
Callable (V call() throws Exception)
│
└─→ Executors.callable(Runnable, result) 轉換
| 介面/類 | 方法 | 返回值 | 拋出異常 | 用途 |
|---|---|---|---|---|
| Runnable | run() | void | 不可拋受檢異常 | 簡單任務、無回傳 |
| Callable<V> | call() | V | 可拋 Exception | 有回傳、可拋異常任務 |
| Future<V> | get()/cancel()/isDone() | V | — | 任務結果控制介面 |
| FutureTask<V> | run() + get() | V | — | Runnable+Future 合體、可包裝兩者 |
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();
}
}
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。
Runnable + ExecutorServiceCallable + ExecutorService.submit()FutureTask 直接 new Thread(ft).start() 或提交池中Future.get(timeout, unit)、cancel()