一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。
用給定的計數 初始化 CounDownLatch
。由于調用了countDown() 方法,所以在當前計數到達零之前,await()
方法會一直受阻塞。之后,會釋放所有等待的線程,await()
的所有后續調用都將立即返回。這種現象只出現一次---計數無法被重置。如果需要重置計數,請考慮使用CyclicBarrier。
CountDownLatch
是一個通用同步工具,它有很多用途。將計數 1 初始化的 CountDownLatch
用作一個簡單的開/關鎖存器,或入口:在通過調用?countDown()的線程打開入口前,所有調用?await()的線程都一直在入口處等待。用 N 初始化的 CountDownLatch
可以使一個線程在 N 個線程完成某項操作之前一直等待,或者使其在某項操作完成 N 次之前一直等待。
CountDownLatch
的一個有用特性是,它不要求調用 countDown
方法的線程等到計數到達零時才繼續,而在所有線程都能通過之前,它只是阻止任何線程繼續通過一個await()。
在接下來給出視頻會議的例子來說明CountDownLacth的用法,視頻會議需要等待多有的參與者都到會后才能開始。視頻會議:
public class VedioConference implements Runnable{private CountDownLatch countDownLatch;public VedioConference(int count) {this.countDownLatch = new CountDownLatch(count);}public void arrive(String name){System.out.println("參與者:"+name+"到達");countDownLatch.countDown();System.out.println("視頻會議還需要等待:"+countDownLatch.getCount()+"名參與者");}@Overridepublic void run() {try {System.out.println("視頻會議共有 :"+countDownLatch.getCount()+"名參與者");countDownLatch.await();System.out.println("所有參與者都已將到達 ");System.out.println("開始會議...");} catch (InterruptedException e) {e.printStackTrace();}} }
參與者:
public class Participant implements Runnable {private VedioConference conference;private String name;public Participant(VedioConference conference, String name) {this.conference = conference;this.name = name;}@Overridepublic void run() {try {//線程隨機休息一段時間Thread.currentThread().sleep((int)(Math.random()*10));} catch (InterruptedException e) {e.printStackTrace();}//調用arrive()表示參與者已經到達 conference.arrive(name);} }
測試類:
public class Main {public static void main(String[] args) {VedioConference conference=new VedioConference(5);Thread conThread=new Thread(conference);conThread.start();for (int i = 0; i <5; i++) {Participant participant=new Participant(conference, "participant"+i);Thread thread=new Thread(participant);thread.start();}} }
運行結果:
視頻會議共有 :5名參與者
參與者:participant2到達
視頻會議還需要等待:4名參與者
參與者:participant3到達
視頻會議還需要等待:3名參與者
參與者:participant1到達
視頻會議還需要等待:2名參與者
參與者:participant4到達
視頻會議還需要等待:1名參與者
參與者:participant0到達
視頻會議還需要等待:0名參與者
所有參與者都已將到達
開始會議...
內存一致性效果:線程中調用 countDown()
之前的操作happen-before緊跟在從另一個線程中對應 await()
成功返回的操作。