欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2016年07月13日 08:59:31   作者:skywangkw  
在Java中和ReadWriteLock.ReadLock一樣,CountDownLatch的本質也是一個"共享鎖",這里我們就來詳解Java多線程編程中CountDownLatch阻塞線程的方法:

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

CountDownLatch函數列表

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

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

201671385520115.jpg (292×140)

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


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

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被喚醒后繼續(xù)執(zhí)行。

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

相關文章

  • Java Stream流零基礎教程

    Java Stream流零基礎教程

    Java8的另一大亮點Stream,它與java.io包里的InputStream和OutputStream是完全不同的概念,下面這篇文章主要給大家介紹了關于Java8中Stream詳細使用方法的相關資料,需要的朋友可以參考下
    2022-11-11
  • mybatis-plus @DS實現(xiàn)動態(tài)切換數據源原理

    mybatis-plus @DS實現(xiàn)動態(tài)切換數據源原理

    本文主要介紹了mybatis-plus @DS實現(xiàn)動態(tài)切換數據源原理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • IDEA中如何引入spring的命名空間

    IDEA中如何引入spring的命名空間

    這篇文章主要介紹了IDEA中如何引入spring的命名空間問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • java PDF添加圖層的方法 支持多頁圖層添加

    java PDF添加圖層的方法 支持多頁圖層添加

    這篇文章主要為大家詳細介紹了java PDF添加圖層的方法,支持多頁圖層添加,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • IDEA通過git回滾到某個提交節(jié)點或某個版本的操作方法

    IDEA通過git回滾到某個提交節(jié)點或某個版本的操作方法

    這篇文章主要介紹了IDEA通過git回滾到某個提交節(jié)點或某個版本的方法,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Spring security實現(xiàn)對賬戶進行加密

    Spring security實現(xiàn)對賬戶進行加密

    這篇文章主要介紹了Spring security實現(xiàn)對賬戶進行加密,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • SpringBoot內部調用事務不起作用問題的解決方案

    SpringBoot內部調用事務不起作用問題的解決方案

    這篇文章主要介紹了SpringBoot事務不起作用問題的解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • Java動態(tài)代理之攔截器的應用

    Java動態(tài)代理之攔截器的應用

    今天小編就為大家分享一篇關于Java動態(tài)代理之攔截器的應用,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • mybatis-plus批量更新updateBatchById問題

    mybatis-plus批量更新updateBatchById問題

    這篇文章主要介紹了mybatis-plus批量更新updateBatchById問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java并發(fā)編程之ConcurrentLinkedQueue源碼詳解

    Java并發(fā)編程之ConcurrentLinkedQueue源碼詳解

    今天帶小伙伴們學習一下Java并發(fā)編程之Java ConcurrentLinkedQueue源碼,本篇文章詳細分析了ConcurrentLinkedQueue源碼,有代碼示例,對正在學習java的小伙伴們很有幫助喲,需要的朋友可以參考下
    2021-05-05

最新評論