主執行緒啟動工作執行緒後,如何取得執行結果?直接呼叫 getter 會因競態條件拿到初始值。
// 工作執行緒
class Worker extends Thread {
private String result;
public void run() {
// 耗時運算
result = "Hello World!";
}
public String getResult() { return result; }
}
// 主執行緒
Worker w = new Worker();
w.start();
while (true) {
String r = w.getResult();
if (!"Hello".equals(r)) { // 初始值不同
System.out.println("結果: " + r);
break;
}
Thread.sleep(100); // 降低 CPU 佔用
}
缺點:忙碌等待浪費 CPU、延遲不可控、難以設定逾時。
// 定義回呼介面
interface ResultCallback {
void onResult(String result);
}
// 工作執行緒接受回呼
class Worker extends Thread {
private final ResultCallback callback;
Worker(ResultCallback cb) { callback = cb; }
public void run() {
String result = "Hello World!";
callback.onResult(result); // 執行完成主動通知
}
}
// 主執行緒實作回呼
public class Main {
public static void main(String[] args) {
new Worker(result -> {
System.out.println("收到結果: " + result);
// 後續處理...
}).start();
// 主執行緒可繼續做其他事
}
}
class Worker extends Thread {
private final List listeners =
Collections.synchronizedList(new ArrayList<>());
public void addListener(ResultListener l) { listeners.add(l); }
public void removeListener(ResultListener l) { listeners.remove(l); }
public void run() {
String result = compute();
// 複製列表避免並發修改
for (ResultListener l : new ArrayList<>(listeners)) {
l.onResult(result);
}
}
}
interface ResultListener {
void onResult(String result);
}
| API | 適用場景 | 特點 |
|---|---|---|
| Future.get() | 單一結果阻塞等待 | 標準阻塞、可逾時、可取消 |
| CompletableFuture | 非阻塞組合、多階段 | 回呼鏈、異常處理、組合運算 |
| CompletableFuture.supplyAsync | 簡單異步計算 | 自動執行緒池、Lambda 友善 |
| ExecutorService.submit(Callable) | 需回傳值的任務 | 標準介面、支援檢查型異常 |