CounDownLatch、CyclicBarrier、Semaphore
CountDownLatch是在java1.5被引入,跟它一起被引入的工具類還有CyclicBarrier、Semaphore、concurrentHashMap和BlockingQueue。
CountDownLatch概念
CountDownLatch是一個同步工具類,用來協調多個執行緒之間的同步,或者說起到執行緒之間的通訊(而不是用作互斥的作用)。
CountDownLatch能夠使一個執行緒在等待另外一些執行緒完成各自工作之後,再繼續執行。使用一個計數器進行實現。計數器初始值為執行緒的數量。當每一個執行緒完成自己任務後,計數器的值就會減一。當計數器的值為0時,表示所有的執行緒都已經完成一些任務,然後在CountDownLatch上等待的執行緒就可以恢復執行接下來的任務。
CountDownLatch的用法
CountDownLatch典型用法:1、某一執行緒在開始執行前等待n個執行緒執行完畢。將CountDownLatch的計數器初始化為new CountDownLatch(n),每當一個任務執行緒執行完畢,就將計數器減1 countdownLatch.countDown(),當計數器的值變為0時,在CountDownLatch上await()的執行緒就會被喚醒。一個典型應用場景就是啟動一個服務時,主執行緒需要等待多個元件載入完畢,之後再繼續執行。
CountDownLatch典型用法:2、實現多個執行緒開始執行任務的最大並行性。注意是並行性,不是併發,強調的是多個執行緒在某一時刻同時開始執行。類似於賽跑,將多個執行緒放到起點,等待發令槍響,然後同時開跑。做法是初始化一個共享的CountDownLatch(1),將其計算器初始化為1,多個執行緒在開始執行任務前首先countdownlatch.await(),當主執行緒呼叫countDown()時,計數器變為0,多個執行緒同時被喚醒。
// 當一個任務需要多工同時進行,提高效率,縮短序列執行時間。cdl.await最後等待位置 public static void main(String[] args) { CountDownLatch cdl = new CountDownLatch(3); ExecutorService executor = new ThreadPoolExecutor(3, 3, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>()); for (int i = 0; i < 3; i++) { executor.execute(() -> {cdl.countDown(); System.out.println(String.valueOf(1111));}); } try { cdl.await(); System.out.println("執行緒結束"); } catch (InterruptedException e) { e.printStackTrace(); } executor.shutdown(); }
CyclicBarrier
CyclicBarrier柵欄類似於賽跑同一起跑線
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(2, () -> {
System.out.println("柵欄中的執行緒執行完成");
});
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(() -> {
try {
cyclicBarrier.await();
System.out.println("執行緒1:" + Thread.currentThread().getName());
} catch (Exception e) {
e.printStackTrace();
}
});
executorService.submit(() -> {
try {
cyclicBarrier.await();
System.out.println("執行緒2:" + Thread.currentThread().getName());
} catch (Exception e) {
e.printStackTrace();
}
});
executorService.shutdown();
}