閉鎖(Latch)實現(xiàn) CountDownLatch 和 柵欄 CyclicBarrier
閉鎖 CountDownLatch 是一個主線程等待多個子線程。
柵欄 CyclicBarrier 是多個線程相互等待,只要一個沒完成,所有線程都等待。
一、閉鎖實現(xiàn) CountDownLatch
CountDownLatch是一個同步工具類,是一種靈活的閉鎖實現(xiàn)。位于concurrent包(jdk1.5引入)下。
常用的ConcurrentHashMap、BlockingQueue、CyclicBarrier(柵欄)也位于該包下。
CountDownLatch的主要作用 等待結(jié)束 同時開始
- 等待結(jié)束:使一個線程等待其他線程完成各自的工作后再執(zhí)行,即并發(fā)場景中的
等待結(jié)束(5種常見的并發(fā)場景)。 - 同時開始(實現(xiàn)最大的并行性):還有另外一種變形應(yīng)用:把計數(shù)器初始值設(shè)為1,多個線程調(diào)用
await()方法,可以實現(xiàn)并發(fā)場景中的同時開始。
CountDownLatch的實現(xiàn)原理
CountDownLatch是一個靈活的閉鎖實現(xiàn),包含一個計數(shù)器,初始值是線程數(shù)量(需要等待的事件個數(shù))在構(gòu)造函數(shù)中設(shè)置。每個線程執(zhí)行完后就減一。
await方法等待計數(shù)器到達(dá)0,表示所有需要等待的事件都已經(jīng)完成,然后繼續(xù)執(zhí)行當(dāng)前線程。
二、柵欄 CyclicBarrier
顧名思義:可循環(huán)(Cyclic)的屏障(Barrier)。讓一組線程到達(dá)一個柵欄屏障都被阻塞,直到最后一個線程到達(dá)。
CyclicBarrier的構(gòu)造方法CyclicBarrier(int parties)的參數(shù)parties表示屏障攔截的線程數(shù)量。
線程調(diào)用await()方法告訴CyclicBarrier我已到達(dá)屏障。然后阻塞當(dāng)前線程。
CyclicBarrier還提供了另一個構(gòu)造方法 CyclicBarrier(int parties, Runnable barrierAction)。
用于在線程到達(dá)屏障時,優(yōu)先執(zhí)行barrierAction這個Runnable對象,用來處理稍微復(fù)雜的業(yè)務(wù)場景。
三、CountDownLatch和CyclicBarrier常見的幾個面試題
- CountDownLatch的概念?
CountDownLatch內(nèi)部使用幾個計數(shù)器,初始大小為要等待線程的個數(shù),每個線程執(zhí)行完畢,計數(shù)器減一。最終計數(shù)器等于0時喚醒主線程。 - CountDownLatch和CyclicBarrier的區(qū)別?
CyclicBarrier是多個線程同時等待,一個沒完,所有等待。 - CountDownLatch的主要方法及使用場景?
主要方法await()和countDown(),使用在等待開始和同時開始等場景下。