public class MyThread extends Thread {
private final String name; // final 保證不可變
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("Hello " + name);
}
}
// 使用
Thread t = new MyThread("World");
t.start();
優點:線程啟動前參數已就緒、final 域線程安全發布、構造器天然線程安全。
缺點:參數多時構造器膨脹,需重載或使用 Builder 模式。
public class MyRunnable implements Runnable {
private String name; // 非 final
public void setName(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("Hello " + name);
}
}
// 使用
MyRunnable task = new MyRunnable();
task.setName("World"); // 必須在 start() 前調用
Thread t = new Thread(task);
t.start();
風險:若 start() 前未完成 Setter 調用,或多線程並發修改,導致可見性問題。
修正:使用 volatile 或 final 配合構造器,或在 start() 前完成所有設置(happens-before 保證)。
// 數據載體
class Data { public int value; }
// 回調接口
interface Worker {
void process(Data data, int... numbers);
}
// 實現
class SumWorker implements Worker {
@Override
public void process(Data data, int... numbers) {
for (int n : numbers) data.value += n;
}
}
// 線程內部動態生成數據並回調
public class CallbackThread extends Thread {
private final Worker worker;
public CallbackThread(Worker worker) {
this.worker = worker;
}
@Override
public void run() {
Random rand = new Random();
Data data = new Data();
int n1 = rand.nextInt(1000);
int n2 = rand.nextInt(2000);
int n3 = rand.nextInt(3000);
worker.process(data, n1, n2, n3); // 回調:將數據推送給外部處理器
System.out.println(n1 + "+" + n2 + "+" + n3 + "=" + data.value);
}
}
// 使用
Thread t = new CallbackThread(new SumWorker());
t.start();
核心場景:線程運行過程中產生數據,需即時交給外部處理器(如流式計算、事件通知、異步回調)。
| 維度 | 構造器注入 | Setter 注入 | 回調函數 |
|---|---|---|---|
| 參數確定時機 | 構造時 | start() 前 | 運行時動態產生 |
| 線程安全性 | 最高 (final) | 需額外保證 | 依賴實現 |
| 適用場景 | 固定初始化參數 | 可選/可變參數 | 運行時產生/流式數據 |
| 耦合度 | 低 | 低 | 中 (依賴接口) |
// 有返回值任務
Callable task = () -> {
// 異步計算
return computeResult(params);
};
Future future = executor.submit(task);
// 主線程其他工作...
Integer result = future.get(); // 阻塞獲取結果
// 或鏈式異步
CompletableFuture.supplyAsync(() -> compute(params))
.thenApply(result -> transform(result))
.thenAccept(System.out::println)
.exceptionally(e -> { log.error(e); return null; });
結論:傳統三種模式理解線程參數傳遞本質;實際項目優先使用 ExecutorService + Future/CompletableFuture 統一管理異步任務參數與結果。