Java子線程如何通知主線程完成任務(wù)?

Java子線程如何通知主線程完成任務(wù)?

Java線程如何優(yōu)雅地通知主線程任務(wù)完成?

高效的多線程編程需要子線程在任務(wù)完成后通知主線程。本文介紹兩種常用的方法:CompletableFuture 和 CountDownLatch,并著重強調(diào)線程安全和最佳實踐。

方法一:使用 CompletableFuture

CompletableFuture 提供了一種簡潔的方式來處理異步操作,并方便地等待多個子線程完成。CompletableFuture.allOf() 方法可以等待所有給定的 CompletableFuture 對象完成。

立即學(xué)習(xí)Java免費學(xué)習(xí)筆記(深入)”;

代碼示例:

List<CompletableFuture<?>> futures = new ArrayList<>();  // 創(chuàng)建并啟動子線程 for (int i = 0; i < 2; i++) {     futures.add(CompletableFuture.runAsync(() -> {         // 模擬子線程任務(wù)         System.out.println("子線程 " + i + " 執(zhí)行完成");     })); }  // 等待所有子線程完成 CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();  // 主線程處理數(shù)據(jù) System.out.println("所有子線程執(zhí)行完成,開始處理數(shù)據(jù)"); }

方法二:使用 CountDownLatch

CountDownLatch 是一種同步工具類,可以用來等待一組事件的完成。初始化時設(shè)置計數(shù)器,每個子線程完成任務(wù)后調(diào)用 countDown() 方法將計數(shù)器減一,主線程調(diào)用 await() 方法等待計數(shù)器變?yōu)榱恪?/p>

代碼示例:

final CountDownLatch latch = new CountDownLatch(2); // 初始化計數(shù)器為 2  // 創(chuàng)建并啟動子線程 for (int i = 0; i < 2; i++) {     new Thread(() -> {         // 模擬子線程任務(wù)         System.out.println("子線程 " + i + " 執(zhí)行完成");         latch.countDown(); // 計數(shù)器減 1     }).start(); }  // 主線程等待子線程完成 try {     latch.await(); } catch (InterruptedException e) {     e.printStackTrace(); }  // 主線程處理數(shù)據(jù) System.out.println("所有子線程執(zhí)行完成,開始處理數(shù)據(jù)"); }

重要提示:

  • 線程安全: ArrayList 不是線程安全的。在并發(fā)環(huán)境下,建議使用 CopyOnWriteArrayList 來替代,以避免數(shù)據(jù)競爭。 如果需要在子線程中修改共享變量,則必須使用合適的同步機制,例如 volatile 關(guān)鍵字或鎖機制,以確保線程安全。
  • 異常處理: 在實際應(yīng)用中,需要完善的異常處理機制,以捕獲并處理子線程中可能發(fā)生的異常。 CompletableFuture 提供了 exceptionally() 方法來處理異常。 CountDownLatch 需要在 await() 方法中捕獲 InterruptedException。

選擇哪種方法取決于具體的應(yīng)用場景。CompletableFuture 更適用于需要處理異步結(jié)果的情況,而 CountDownLatch 更適用于簡單的等待多個線程完成的情況。 記住始終優(yōu)先考慮線程安全和健壯的異常處理。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊5 分享