多線程-併發:介紹CountDownLatch

----------------------------------------------------筆者才疏學淺,如有錯誤,請各位大佬指正------------------------------------------------------------

注:本文是筆者在網絡公開課學習到,總結而成的。

 

這篇博客主要爲大家介紹CountDownLatch、CyclicBarrier、Phaser三個類。其中CountDownLatch、CyclicBarrier自JDK1.5出現,而Phaser從JDK1.7纔出現。

先來了解一下基礎理論知識:

併發協同原理:多線程併發,協同完成一件事,但需要根據需求阻塞一些線程以完成工作。

併發編程套路:①併發的是什麼?②在什麼地方協同?③誰來等待?誰來通知?

併發方式:①synchronized,Object.wait(),Object.notify(),Object.notifyAll();

                  ②Lock以及Conditional.await(),Conditional.signal();

                  ③java併發包下的協同API

 

本文將重點介紹:CountDownLatch倒計數鎖存器

CyclicBarrier、Phaser將在分別在本系列(二)(三)中介紹

另外還有Semaphone計數信息器,請有興趣的大佬自行了解。本文不做介紹。

 

看過《天龍八部》的都應該清楚:段延慶葉二孃南海鱷神雲中鶴相約在一個山頂準備刺殺段正淳。這裏只說“相約”的事情。

場景:四個人必須都到齊,才能匯合準備下一階段的事情。

分析:從線程角度考慮,必須四個線程都完成“到”,整體進度才能執行下一個階段;有人不“到”則“到”的線程阻塞,直到全部“到”齊,所有“到”的都被喚醒。

基於這種情況,向大家介紹CountDownLatch類:

//本類用途:協同控制一個或多個線程等待其他線程中執行的一組操作完成,在繼續執行。
public class CountDownLatch {
    //構造方法
    //count執行等待的條件數(操作數、任務數),不可再更改
    public class CountDownLatch(int count) {...}

    //等待方法
    //await()阻塞等待線程知道條件都滿足(count等待條件計數減少到0)
    //如果count已是0,則不會阻塞,繼續執行
    public void await(){...}

    //條件完成減計數方法
    //每一條件在完成時,都調用countDown()來對count計數減一。
    public void countDown() {}

    //以下方法不是本文重點
        
    //阻塞等待最多最長時間。
    //返回true表示的等待條件到達;false表示條件未到達但是時間到了。
    public boolean await(long timeout , TimeUnit unit){...}
    
    //獲取當前計數值,該方法常用於調試或測試。
    public long getCount() {}
}

以上就是CountDownLatch類部分代碼(其中有一個私有靜態類Sync,其繼承自AbstractQueuedSynchronizer,需要了解CountDownLatch原理的請自行閱讀)。

注意!——只可使用一次,不可重複使用!

每個CountdDownLatch對象,只可使用一次,計數變爲0後。就不可再用了!

CountDownLatch使用套路:①new設數量②設定中斷點await③每個線程完成前countdown

        CountDownLatch countDownLatch = new CountDownLatch(4);
		for(int i = 0 ; i < 4 ; i++) {
			new Thread(){
				@Override
				public void run() {
					System.out.println("四大惡人到達數+1");
					countDownLatch.countDown();
					try {
						countDownLatch.await();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}.start();;
		}
		
		System.out.println("磨刀霍霍向正淳");

沒錯學到了套路就是這麼簡單。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章