| 維度 | 繼承 Thread | 實現 Runnable | Callable + Future |
|---|---|---|---|
| 核心機制 | 子類重寫 run() | 實現 run(),作為 Thread target | 實現 call(),返回結果,FutureTask 包裝 |
| 返回值 | 無 | 無 | 有 (Future.get()) |
| 拋出異常 | 無法拋出受檢異常 | 無法拋出受檢異常 | 可拋出受檢異常 |
| 線程控制 | this 即當前線程 | Thread.currentThread() 獲取 | FutureTask 控制執行 |
| 繼承限制 | 單繼承,無法 extends 其他類 | 可實現多接口、extends 其他類 | 同 Runnable |
| 資源共享 | 較難實現 | 同一 Runnable 實例可共享數據 | 同 Runnable |
| 適用場景 | 簡單獨立任務 | 多線程賣票、生產者消費者 | 需要結果/異常的異步計算 |
public class ThreadExtendDemo extends Thread {
private int count = 0;
@Override
public void run() {
for (; count < 100; count++) {
System.out.println(getName() + " : " + count); // getName() 直接可用
}
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
if (i == 20) {
new ThreadExtendDemo().start(); // 啟動線程
new ThreadExtendDemo().start();
}
}
}
}
優點:代碼簡單,`this` 直接操作線程屬性。
缺點:佔用繼承名額,無返回值,異常處理弱。
public class RunnableDemo implements Runnable {
private int count = 0; // 共享數據
@Override
public void run() {
for (; count < 100; count++) {
System.out.println(Thread.currentThread().getName() + " : " + count);
}
}
public static void main(String[] args) {
RunnableDemo task = new RunnableDemo(); // 單實例共享 count
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
if (i == 20) {
new Thread(task, "線程-A").start();
new Thread(task, "線程-B").start();
}
}
}
}
優點:解耦任務與線程,**同一任務實例可被多線程共享**,支持繼承其他類,體現面向對象分離關注點。
缺點:需 `Thread.currentThread()` 獲取當前線程,無返回值。
public class CallableDemo implements Callable {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
sum += i;
}
return sum; // 返回結果
}
public static void main(String[] args) {
CallableDemo task = new CallableDemo();
FutureTask future = new FutureTask<>(task); // 包裝
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
if (i == 20) {
new Thread(future, "有返回值線程").start(); // FutureTask 實現 Runnable
}
}
try {
System.out.println("主線程等待結果...");
Integer result = future.get(); // 阻塞獲取結果
System.out.println("子線程返回: " + result); // 4950
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
核心類關係**:
Callable→ FutureTask (實現 RunnableFuture → Runnable + Future ) ↓ Thread(target=FutureTask) ↓ future.get() 獲取 V
ExecutorService executor = Executors.newFixedThreadPool(3);
List> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
final int taskId = i;
futures.add(executor.submit(() -> {
// 異步計算
Thread.sleep(100);
return taskId * 2;
}));
}
// 收集結果
for (Future f : futures) {
System.out.println("結果: " + f.get()); // 阻塞直到完成
}
executor.shutdown();
// 異步計算鏈
CompletableFuture.supplyAsync(() -> heavyCompute())
.thenApply(result -> transform(result))
.thenAccept(System.out::println)
.exceptionally(ex -> { log.error(ex); return defaultValue; });
// 組合多個異步任務
CompletableFuture.allOf(
CompletableFuture.supplyAsync(() -> task1()),
CompletableFuture.supplyAsync(() -> task2())
).join(); // 等待全部完成
需要返回值或拋受檢異常?
├── 是 → Callable + FutureTask / ExecutorService.submit(Callable)
│ └── JDK 8+ 首選 CompletableFuture (鏈式、組合、異常處理)
└── 否 → 任務需共享數據/狀態?
├── 是 → 實現 Runnable (單實例多線程共享)
└── 否 → 簡單獨立任務?
├── 是 → 繼承 Thread / 實現 Runnable 均可
└── 否 → 複雜線程控制 → 考慮 Thread 子類或線程池