CountDownLatch和CyclicBarrier的簡單使用
轉自:http://www.kissyu.org/2016/07/18/%E5%AD%A6%E4%B9%A0%E4%BD%BF%E7%94%A8CountDownLatch%E5%92%8CCyclicBarrier/
簡介
CountDownLatch和CyclicBarrier都是執行緒同步的輔助工具。
CountDownLatch
CountDownLatch可以想象成一個上了N把鎖的門栓。當某個執行緒呼叫await方法時,它會去檢測當前門栓上是否有鎖,如果有鎖的話就繼續執行,否則就繼續等待,知道全部的鎖都被解除。可以通過呼叫countDown方法來從門栓上解除一把鎖。
有一個十分典型的應用場景就是利用CountDownLatch來保證執行緒同時開始執行或者保證當前執行緒等待其他執行緒全部結束之後繼續執行,程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
public class TestDemo { public static void main(String args[]) throws InterruptedException { int threadCount = 10; CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch doneSignal = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { // create and start threads new Thread(new Worker(startSignal, doneSignal, "th-" + i)).start(); } System.out.println("sub threads waiting for main thread"); startSignal.countDown(); // let all threads proceed doneSignal.await(); // wait for all to finish System.out.println("sub threads complete"); } static class Worker implements Runnable { private final CountDownLatch startSignal; private final CountDownLatch doneSignal; private final String name; Worker(CountDownLatch startSignal, CountDownLatch doneSignal, String name) { this.startSignal = startSignal; this.doneSignal = doneSignal; this.name = name; } public void run() { try { startSignal.await(); doWork(); doneSignal.countDown(); } catch (InterruptedException ex) { } // return; } void doWork() { System.out.println(this.name + " is doing work"); } } }
|
執行結果如下:
1 2 3 4 5 6 7 8 9 10 11 12
|
sub threads waiting for main thread th-0 is doing work th-3 is doing work th-4 is doing work th-1 is doing work th-2 is doing work th-9 is doing work th-8 is doing work th-7 is doing work th-5 is doing work th-6 is doing work sub threads complete
|
CyclicBarrier
我們可以用學校春遊之前在操場集合的這個場景來理解CyclicBarrier。一個班級如果要出發,那麼必須要等班裡所有的人都到了才能走。到了集合地點的人需要簽到,然後等待其他人,這個過程就像CyclicBarrier中的await方法。當所有人都簽到完畢,班主任會上前說一些注意事項,這一步就像下面程式碼中的barrierAction。然後,所有人才可以出發,在程式碼中的表現就是繼續執行await之後的方法。示例程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
public class TestDemo { public static void main(String args[]) throws InterruptedException { int threadCount = 10; Runnable barrierAction = new Runnable() { public void run() { System.out.println("sub threads complete"); } }; CyclicBarrier barrier = new CyclicBarrier(threadCount, barrierAction); List<Thread> threads = new ArrayList<>(threadCount); for (int i = 0; i < threadCount; i++) { Thread thread = new Thread(new Worker(barrier, "th-" + i)); threads.add(thread); thread.start(); } // wait until done for (Thread thread : threads) { thread.join(); } } public static class Worker implements Runnable { private CyclicBarrier barrier; private String name; Worker(CyclicBarrier barrier, String name) { this.barrier = barrier; this.name = name; } public void run() { try { doWork(); barrier.await(); System.out.println(name + " waiting finish"); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } private void doWork() { System.out.println(name + " is doing work"); } } }
|
執行結果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
th-0 is doing work th-1 is doing work th-2 is doing work th-3 is doing work th-4 is doing work th-5 is doing work th-6 is doing work th-7 is doing work th-8 is doing work th-9 is doing work sub threads complete th-9 waiting finish th-0 waiting finish th-1 waiting finish th-2 waiting finish th-4 waiting finish th-3 waiting finish th-5 waiting finish th-7 waiting finish th-6 waiting finish th-8 waiting finish
|
區別
這兩個類,在定義上的區別似乎不大。一個是latch,一個是barrier,都體現了阻塞的意思,並且呼叫await的時候都會阻塞。但是他們阻塞時的執行緒的關係是不一樣的。對於CountDownLatch來說,是一個或多個執行緒在等待一個或多個執行緒,他們的等待關係從巨集觀的角度來看只有一組。而對於CyclicBarrier來說,是所有的執行緒在互相等待,他們的等待關係是交叉的。
另外一個區別是,CyclicBarrier的barrier是可以複用的(呼叫reset方法),但是CountDownLatch的latch只能用一次。這個區別在實際的業務當中會產生一定的影響。
相關文章
- CyclicBarrier And CountDownLatchCountDownLatch
- JUC(3)---CountDownLatch、CyclicBarrier和AQSCountDownLatchAQS
- CountDownLatch和CyclicBarrier區別及詳解CountDownLatch
- Java併發之CountDownLatch、CyclicBarrier和SemaphoreJavaCountDownLatch
- CyclicBarrier、CountDownLatch以及Semaphore使用及其原理分析CountDownLatch
- 【對線面試官】CountDownLatch和CyclicBarrier的區別面試CountDownLatch
- CyclicBarrier、CountDownLatch與Semaphore的小記CountDownLatch
- Java併發—— CountDownLatch與CyclicBarrierJavaCountDownLatch
- Java併發程式設計:CountDownLatch、CyclicBarrier和SemaphoreJava程式設計CountDownLatch
- CountDownLatch、CyclicBarrier、Semaphore、Exchanger 的詳細解析CountDownLatch
- Java 併發包之CountDownLatch、CyclicBarrierJavaCountDownLatch
- 面試官:說說CountDownLatch,CyclicBarrier,Semaphore的原理?面試CountDownLatch
- 高併發之ReentrantLock、CountDownLatch、CyclicBarrierReentrantLockCountDownLatch
- 07 併發工具類CountDownLatch、CyclicBarrier、Semaphore使用及原始碼分析CountDownLatch原始碼
- CountDownLatch和CyclicBarrier 傻傻的分不清?超長精美圖文又來了CountDownLatch
- Java 併發工具類 CountDownLatch、CyclicBarrier、Semaphore、ExchangerJavaCountDownLatch
- java多執行緒10:併發工具類CountDownLatch、CyclicBarrier和SemaphoreJava執行緒CountDownLatch
- 併發-6-wait、notify、Semaphore、CountDownLatch、CyclicBarrierAICountDownLatch
- 大白話說java併發工具類-CountDownLatch,CyclicBarrierJavaCountDownLatch
- 【高併發】AQS中的CountDownLatch、Semaphore與CyclicBarrier用法總結AQSCountDownLatch
- Kdevelop的簡單使用和簡單除錯dev除錯
- JUC併發程式設計之Semaphore、CountDownLatch、CyclicBarrier協同工具程式設計CountDownLatch
- 執行緒執行順序——CountDownLatch、CyclicBarrier 、join()、執行緒池執行緒CountDownLatch
- Java:多執行緒等待所有執行緒結束(CountDownLatch/CyclicBarrier) .Java執行緒CountDownLatch
- Java併發包5--同步工具CountDownLatch、CyclicBarrier、Semaphore的實現原理解析JavaCountDownLatch
- pyenv的安裝和簡單使用
- java-多執行緒-CountDownLatch(閉鎖) CyclicBarrier(柵欄) Semaphore(訊號量)-Java執行緒CountDownLatch
- JUC之CountDownLatch的原始碼和使用場景分析CountDownLatch原始碼
- Docker安裝和簡單使用Docker
- InnoSetup簡單教程一,安裝使用和簡單測試
- iOS UICollectionView的簡單使用和常用代理方法iOSUIView
- Python中*args和**kwargs 的簡單使用Python
- SearchView的簡單使用和模擬搜尋View
- redis的簡單使用和介紹(轉載)Redis
- Java高併發之CyclicBarrier簡介Java
- docker的簡單使用Docker
- postman的簡單使用Postman
- RecyclerView的簡單使用View