Java中的CountDownLatch閉鎖詳解
Java中的CountDownLatch閉鎖
CountDownLatch是對synchronization拓展,允許一個或多個線程等待,直到在其他線程中執(zhí)行的一組操作完成。
CountDownLatch用給定的計數(shù)初始化。
await屬于阻塞方法,直到當前計數(shù)達到零,由于countDown方法被調(diào)用,然后釋放所有await等待的線程,并立即返回線程后續(xù)的await調(diào)用邏輯。
CountDownLatch是一種一次性現(xiàn)象——計數(shù)無法重置。
如果需要重新設(shè)置計數(shù)的版本,可以考慮使用CyclicBarrier。
CountDownLatch是一種通用的同步工具,可以用于多種目的。
初始化一個count為1的CountDownLatch用作一個簡單的on/off latch或gate:所有調(diào)用wait的線程都在gate處等待,直到它被調(diào)用countDown的線程打開。
一個初始化為N的CountDownLatch可以用來讓一個線程等待,直到N個線程完成了某個操作,或者某個操作已經(jīng)完成了N次。
CountDownLatch的一個有用特性是,它不要求調(diào)用countDown的線程等待計數(shù)達到零才繼續(xù),它只是防止任何線程繼續(xù)等待,直到所有線程都通過。
示例用法:這里有兩個類,其中一組工作線程使用兩個倒計時鎖存器:
第一個是啟動信號,它阻止任何worker繼續(xù)工作,直到驅(qū)動程序準備好讓它們繼續(xù)工作;
第二個是一個完成信號,它允許驅(qū)動程序等待所有worker完成。
class Driver { // ... void main() throws InterruptedException { CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch doneSignal = new CountDownLatch(N); for (int i = 0; i < N; ++i) // create and start threads new Thread(new Worker(startSignal, doneSignal)).start(); doSomethingElse(); // 預(yù)備工作邏輯 startSignal.countDown(); // 讓所有Worker開始工作 doSomethingElse(); doneSignal.await(); // 等待所有Worker完成自己邏輯 } } class Worker implements Runnable { private final CountDownLatch startSignal; private final CountDownLatch doneSignal; Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { this.startSignal = startSignal; this.doneSignal = doneSignal; } public void run() { try { startSignal.await(); doWork(); doneSignal.countDown(); } catch (InterruptedException ex) {} // return; } void doWork() { ... } }
另一種典型的用法是將一個問題分成N個部分,用一個Runnable描述每個部分,該Runnable執(zhí)行該部分并在鎖存器上計數(shù),然后將所有Runnables排隊到一個執(zhí)行器。當所有子部件都完成時,協(xié)調(diào)線程將能夠通過并等待。(當線程必須以這種方式重復(fù)倒數(shù)時,使用CyclicBarrier。)
class Driver2 { // ... void main() throws InterruptedException { CountDownLatch doneSignal = new CountDownLatch(N); Executor e = ... for (int i = 0; i < N; ++i) // 創(chuàng)建和開啟線程 e.execute(new WorkerRunnable(doneSignal, i)); doneSignal.await(); // 等待所有Worker完成邏輯操作 } } class WorkerRunnable implements Runnable { private final CountDownLatch doneSignal; private final int i; WorkerRunnable(CountDownLatch doneSignal, int i) { this.doneSignal = doneSignal; this.i = i; } public void run() { try { doWork(i); doneSignal.countDown(); } catch (InterruptedException ex) {} // return; } void doWork() { ... } }
內(nèi)存一致性效應(yīng):在計數(shù)達到零之前,在另一個線程中調(diào)用countDown()之前的動作發(fā)生——在從相應(yīng)的await()成功返回之后的動作發(fā)生之前。
CountDownLatch底層通過內(nèi)部類Sync繼承AbstractQueuedSynchronizer類;
計數(shù)器字段使用內(nèi)存語義volatile修飾,private volatile int state;
到此這篇關(guān)于Java中的CountDownLatch閉鎖詳解的文章就介紹到這了,更多相關(guān)CountDownLatch閉鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java.lang.String和java.util.NClob互相轉(zhuǎn)換方式
這篇文章主要介紹了java.lang.String和java.util.NClob互相轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09VSCode+Gradle搭建Java開發(fā)環(huán)境實現(xiàn)
這篇文章主要介紹了VSCode+Gradle搭建Java開發(fā)環(huán)境實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07分享關(guān)于JAVA 中使用Preferences讀寫注冊表時要注意的地方
這篇文章介紹了關(guān)于JAVA 中使用Preferences讀寫注冊表時要注意的地方,有需要的朋友可以參考一下2013-08-08Spring?boot?運用策略模式實現(xiàn)避免多次使用if的操作代碼
這篇文章主要介紹了Spring?boot?運用策略模式實現(xiàn),避免多次使用if,使用策略模式后,新加一種支付策略時,只需要在策略枚舉中添加新加的策略信息,外加一個策略類即可,而不再需要添加新的if判斷,需要的朋友可以參考下2022-08-08SpringSecurity+JWT實現(xiàn)登錄流程分析
Spring Security 是一個功能強大且高度可定制的身份驗證和訪問控制框架,它是為Java應(yīng)用程序設(shè)計的,特別是那些基于Spring的應(yīng)用程序,下面給大家介紹SpringSecurity+JWT實現(xiàn)登錄流程,感興趣的朋友一起看看吧2024-12-12Java?從json提取數(shù)組并轉(zhuǎn)換為list的操作方法
這篇文章主要介紹了Java?從json提取出數(shù)組并轉(zhuǎn)換為list,使用getJSONArray()獲取到j(luò)sonarray后,再將jsonArray轉(zhuǎn)換為字符串,最后將字符串解析為List列表,本文通過實例代碼給大家詳細講解,需要的朋友可以參考下2022-10-10