根據 UML 活動圖:
public class TaskScheduler {
public static void main(String[] args) throws InterruptedException {
// 共享同步對象
final Object lock45 = new Object();
final boolean[] done = {false, false}; // [任務4完成, 任務5完成]
// 線程1:執行 1→3→5
Thread t1 = new Thread(() -> {
executeTask(1); executeTask(3); executeTask(5);
synchronized (lock45) {
done[1] = true;
lock45.notifyAll();
}
});
// 線程2:執行 2→4
Thread t2 = new Thread(() -> {
executeTask(2); executeTask(4);
synchronized (lock45) {
done[0] = true;
lock45.notifyAll();
}
});
// 線程3:執行 7(獨立)
Thread t3 = new Thread(() -> executeTask(7));
// 啟動所有線程
t1.start(); t2.start(); t3.start();
// 主線程等待 4 和 5 完成
synchronized (lock45) {
while (!done[0] || !done[1]) {
lock45.wait();
}
}
// 執行任務6
executeTask(6);
// 等待所有線程結束
t1.join(); t2.join(); t3.join();
System.out.println("所有任務完成");
}
static void executeTask(int n) {
System.out.println("執行任務 " + n);
try { Thread.sleep(100); } catch (InterruptedException e) {}
}
}
CompletableFuture chain1 = CompletableFuture.runAsync(() -> executeTask(1))
.thenRunAsync(() -> executeTask(3))
.thenRunAsync(() -> executeTask(5));
CompletableFuture chain2 = CompletableFuture.runAsync(() -> executeTask(2))
.thenRunAsync(() -> executeTask(4));
CompletableFuture chain3 = CompletableFuture.runAsync(() -> executeTask(7));
// 等待 chain1 和 chain2 完成,再執行任務6
CompletableFuture.allOf(chain1, chain2).thenRunAsync(() -> executeTask(6));
// 等待所有完成
CompletableFuture.allOf(chain1, chain2, chain3).join();
CountDownLatch latch45 = new CountDownLatch(2); // 等待任務4和5
new Thread(() -> { executeTask(1); executeTask(3); executeTask(5); latch45.countDown(); }).start();
new Thread(() -> { executeTask(2); executeTask(4); latch45.countDown(); }).start();
new Thread(() -> executeTask(7)).start();
latch45.await(); // 阻塞直到計數歸零
executeTask(6);
| 方案 | 優點 | 缺點 | 適用版本 |
|---|---|---|---|
| Thread + wait/notify | 底層可控,無依賴 | 代碼冗長,易出錯 | 所有版本 |
| CountDownLatch | 語義清晰,簡潔 | 一次性計數器 | Java 5+ |
| CompletableFuture | 鏈式調用,異常傳播,函數式 | 學習曲線稍陡 | Java 8+ |