Java中的CountDownLatch閉鎖詳解
Java中的CountDownLatch閉鎖
CountDownLatch是對synchronization拓展,允許一個或多個線程等待,直到在其他線程中執(zhí)行的一組操作完成。
CountDownLatch用給定的計數(shù)初始化。
await屬于阻塞方法,直到當前計數(shù)達到零,由于countDown方法被調(diào)用,然后釋放所有await等待的線程,并立即返回線程后續(xù)的await調(diào)用邏輯。
CountDownLatch是一種一次性現(xiàn)象——計數(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(); // 預備工作邏輯
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)線程將能夠通過并等待。(當線程必須以這種方式重復倒數(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)存一致性效應:在計數(shù)達到零之前,在另一個線程中調(diào)用countDown()之前的動作發(fā)生——在從相應的await()成功返回之后的動作發(fā)生之前。
CountDownLatch底層通過內(nèi)部類Sync繼承AbstractQueuedSynchronizer類;

計數(shù)器字段使用內(nèi)存語義volatile修飾,private volatile int state;
到此這篇關于Java中的CountDownLatch閉鎖詳解的文章就介紹到這了,更多相關CountDownLatch閉鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java使用MulticastSocket實現(xiàn)群聊應用程序
這篇文章主要為大家詳細介紹了Java使用MulticastSocket實現(xiàn)群聊應用程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05
springboot使用之多個filter的執(zhí)行順序以及配置方式
這篇文章主要介紹了springboot使用之多個filter的執(zhí)行順序以及配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
mybatis-plus QueryWrapper 添加limit方式
這篇文章主要介紹了mybatis-plus QueryWrapper 添加limit方式,具有很好的參考價值,希望對大家有所2022-01-01
Spring Boot 中集成 Lombok 和 MapStruct最
文章詳解SpringBoot項目中Lombok與MapStruct整合實踐,涵蓋版本兼容、IDE配置、代碼分層、映射配置、測試驗證及性能優(yōu)化,重點解決注解沖突、依賴注入等常見問題,強調(diào)分層管理和組件掃描配置,提升開發(fā)效率與代碼簡潔性,本文給大家介紹的非常詳細,感興趣的朋友一起看看吧2025-08-08

