国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

詳解Java多線程編程中CountDownLatch阻塞線程的方法

2019-11-26 14:04:19
字體:
來源:轉載
供稿:網友

直譯過來就是倒計數(CountDown)門閂(Latch)。倒計數不用說,門閂的意思顧名思義就是阻止前進。在這里就是指 CountDownLatch.await() 方法在倒計數為0之前會阻塞當前線程。
CountDownLatch是一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。
CountDownLatch 的作用和 Thread.join() 方法類似,可用于一組線程和另外一組線程的協作。例如,主線程在做一項工作之前需要一系列的準備工作,只有這些準備工作都完成,主線程才能繼續它的工作。這些準備工作彼此獨立,所以可以并發執行以提高速度。在這個場景下就可以使用 CountDownLatch 協調線程之間的調度了。在直接創建線程的年代(Java 5.0 之前),我們可以使用 Thread.join()。在 JUC 出現后,因為線程池中的線程不能直接被引用,所以就必須使用 CountDownLatch 了。
CountDownLatch類是一個同步計數器,構造時傳入int參數,該參數就是計數器的初始值,每調用一次countDown()方法,計數器減1,計數器大于0 時,await()方法會阻塞程序繼續執行。 CountDownLatch可以看作是一個倒計數的鎖存器,當計數減至0時觸發特定的事件。利用這種特性,可以讓主線程等待子線程的結束。 下面以一個模擬運動員比賽的例子加以說明。
CountDownLatch的一個非常典型的應用場景是:有一個任務想要往下執行,但必須要等到其他的任務執行完畢后才可以繼續往下執行。假如我們這個想要繼續往下執行的任務調用一個CountDownLatch對象的await()方法,其他的任務執行完自己的任務后調用同一個CountDownLatch對象上的countDown()方法,這個調用await()方法的任務將一直阻塞等待,直到這個CountDownLatch對象的計數值減到0為止。

CountDownLatch函數列表

CountDownLatch(int count)構造一個用給定計數初始化的 CountDownLatch。// 使當前線程在鎖存器倒計數至零之前一直等待,除非線程被中斷。void await()// 使當前線程在鎖存器倒計數至零之前一直等待,除非線程被中斷或超出了指定的等待時間。boolean await(long timeout, TimeUnit unit)// 遞減鎖存器的計數,如果計數到達零,則釋放所有等待的線程。void countDown()// 返回當前計數。long getCount()// 返回標識此鎖存器及其狀態的字符串。String toString()

CountDownLatch數據結構
CountDownLatch的UML類圖如下:

201671385520115.jpg (292×140)

CountDownLatch的數據結構很簡單,它是通過"共享鎖"實現的。它包含了sync對象,sync是Sync類型。Sync是實例類,它繼承于AQS。


CountDownLatch的使用示例
下面通過CountDownLatch實現:"主線程"等待"5個子線程"全部都完成"指定的工作(休眠1000ms)"之后,再繼續運行。

import java.util.concurrent.CountDownLatch;import java.util.concurrent.CyclicBarrier;public class CountDownLatchTest1 { private static int LATCH_SIZE = 5; private static CountDownLatch doneSignal; public static void main(String[] args) {  try {   doneSignal = new CountDownLatch(LATCH_SIZE);   // 新建5個任務   for(int i=0; i<LATCH_SIZE; i++)    new InnerThread().start();   System.out.println("main await begin.");   // "主線程"等待線程池中5個任務的完成   doneSignal.await();   System.out.println("main await finished.");  } catch (InterruptedException e) {   e.printStackTrace();  } } static class InnerThread extends Thread{  public void run() {   try {    Thread.sleep(1000);    System.out.println(Thread.currentThread().getName() + " sleep 1000ms.");    // 將CountDownLatch的數值減1    doneSignal.countDown();   } catch (InterruptedException e) {    e.printStackTrace();   }  } }}

運行結果:

main await begin.Thread-0 sleep 1000ms.Thread-2 sleep 1000ms.Thread-1 sleep 1000ms.Thread-4 sleep 1000ms.Thread-3 sleep 1000ms.main await finished.

結果說明:主線程通過doneSignal.await()等待其它線程將doneSignal遞減至0。其它的5個InnerThread線程,每一個都通過doneSignal.countDown()將doneSignal的值減1;當doneSignal為0時,main被喚醒后繼續執行。

PS:CountDownLatch和CyclicBarrier的區別:
(1) CountDownLatch的作用是允許1或N個線程等待其他線程完成執行;而CyclicBarrier則是允許N個線程相互等待。
(2) CountDownLatch的計數器無法被重置;CyclicBarrier的計數器可以被重置后使用,因此它被稱為是循環的barrier。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 顺昌县| 遂溪县| 丹东市| 卓资县| 衢州市| 乐清市| 新化县| 晋江市| 上杭县| 湖北省| 和平区| 滦南县| 阿坝| 奈曼旗| 方城县| 环江| 漠河县| 抚顺市| 商水县| 荔波县| 遵化市| 宿州市| 张家口市| 鹤峰县| 莒南县| 景洪市| 陆丰市| 天峻县| 鄂尔多斯市| 霍林郭勒市| 玉环县| 都安| 彰化县| 平凉市| 光山县| 留坝县| 绿春县| 霍林郭勒市| 阳山县| 常山县| 乳山市|