在多線程編程中,主線程常常需要等待多個子線程完成任務后才能繼續執行后續操作。本文介紹兩種常用的方法:CompletableFuture.allOf 和 CountDownLatch,來優雅地解決這個問題。
方法一:使用 CompletableFuture.allOf
CompletableFuture.allOf 方法接收多個 CompletableFuture 對象作為參數,并返回一個新的 CompletableFuture。只有當所有輸入的 CompletableFuture 都完成時,這個新的 CompletableFuture 才會完成。
立即學習“Java免費學習筆記(深入)”;
示例代碼:
CompletableFuture<Void> futureA = CompletableFuture.runAsync(() -> { // 子線程 A 的任務 }); CompletableFuture<Void> futureB = CompletableFuture.runAsync(() -> { // 子線程 B 的任務 }); CompletableFuture<Void> allDone = CompletableFuture.allOf(futureA, futureB); allDone.thenRun(() -> { // 所有子線程都執行完畢后執行此代碼 // 處理共享數據 });
方法二:使用 CountDownLatch
CountDownLatch 是一個計數器,可以用來同步多個線程。主線程調用 await() 方法等待計數器減為 0,而子線程完成任務后調用 countDown() 方法將計數器減 1。
示例代碼:
CountDownLatch latch = new CountDownLatch(2); // 初始化計數器為 2 (兩個子線程) Thread threadA = new Thread(() -> { // 子線程 A 的任務 latch.countDown(); // 計數器減 1 }); Thread threadB = new Thread(() -> { // 子線程 B 的任務 latch.countDown(); // 計數器減 1 }); threadA.start(); threadB.start(); try { latch.await(); // 主線程等待計數器減為 0 } catch (InterruptedException e) { e.printStackTrace(); } // 所有子線程都執行完畢后執行此代碼 // 處理共享數據
線程安全與共享變量
如果主線程和子線程需要共享數據(例如 ArrayList),必須確保數據訪問的線程安全。ArrayList 不是線程安全的,建議使用線程安全的替代方案,例如 ConcurrentHashMap 或 CopyOnWriteArrayList。
選擇哪種方法取決于具體場景。CompletableFuture 更適用于基于異步操作的場景,而 CountDownLatch 更適用于需要精確控制線程同步的場景。 兩種方法都能有效地解決主線程等待子線程完成的問題,確保程序的正確性和穩定性。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END