這篇文章主要介紹了Java CountDownLatch完成非同步回呼實例詳解的相關資料,需要的朋友可以參考下
Java CountDownLatch完成異步回呼實例詳解
實例程式碼:
public class AsyncDemo { private static void doSomeTask() { System.out.println("Hello World"); } private static void onCompletion() { System.out.println("All tasks finished"); } public static void main(String[] args) { ExecutorService executor = Executors.newCachedThreadPool(); final CountDownLatch latch = new CountDownLatch(2); executor.execute(new Task(latch)); executor.execute(new Task(latch)); executor.execute(() -> { try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } onCompletion(); }); executor.shutdown(); } private static class Task implements Runnable { /** * CountDownLatch 是JDK提供的一个简单的线程监测工具 * 基于简单的计数,调用countDown()方法表明当前线程已经终止 * 在监测线程中调用await()方法,该方法会一直挂起直到所有其它线程终止 */ private final CountDownLatch latch; public Task(CountDownLatch latch) { this.latch = latch; } @Override public void run() { try { doSomeTask(); } catch (Exception e) { e.printStackTrace(); } finally { latch.countDown(); } } } }
這裡有兩點需要補充:
1.如果你是用main方法啟動的線程,這種呼叫方法是沒有問題的,JDK會確保所有執行緒都終止以後main方法才退出。但如果main方法不是非同步任務的啟動者(如JUnit,Spring,Tomcat),一旦啟動之後laucher將會失去對執行緒的控制。如在JUnit中laucher提交完任務後就會被認為所有流程已完成,其它執行緒會被強行終止。
2.正因為如此,請根據環境使用正確的Executor。例如,在web環境中,應該選用tomcat(或Spring)管理的線程池作為Executor,這樣才能確保web應用對於異步任務的整個生命週期具有控制權;如果你選用JDK的線程池有什麼後果呢?任務也許可以正常執行,當一旦你終止web-app,正在執行的非同步線程並不會被正常kill掉,並由此造成記憶體洩漏或其它不可預見的後果。
以上是Java CountDownLatch完成非同步回呼範例程式碼分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!