Java并发工具类(闭锁CountDownLatch)
并發工具類系列:
Java并發工具類(閉鎖CountDownLatch)
Java并發工具類(柵欄CyclicBarrier)
Java并發工具類(信號量Semaphore)
閉鎖是一種同步工具類,可以延遲線程的進度直到其到達終止狀態。
CountDownLatch是一種靈活的閉鎖實現,它可以使一個或者多個線程等待一組事件的發生。
閉鎖狀態包含一個計數器,該計數器被初始化為一個正數,表示需要等待的事件數量。countDown方法遞減計數器,表示已經有一個事件已經發生了。而await方法等待計數器達到0,這表示所有需要等待的事件都已經發生。如果計數器的值非0,那么await會一直阻塞直到計數器為0,或者等待中的線程中斷或者超時。 下面,我們以經典的運動員賽跑舉例:
我們在這里設置了兩個門,一個是開始門,一個是結束門。- 開始門: 所有運動員處于準備狀態,等待教練的槍聲。這時候運動員為n個,槍響只需要一聲,等待的這一聲槍響到了,開始門也就打開了,所有運動員開始跑。
- 結束門: 教練等待所有運動員,當最后一個運動員也沖破底線,教練才能宣布所有人到達終點,這時候是教練等待n個運動員,直到n為0。
下面我們根據具體的代碼來演示CountDownLatch的用法:
package concurrency;import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit;class Runner implements Runnable {private static int counter = 0;private final int id = counter++;private static Random rand= new Random(47);private final CountDownLatch start_latch;private final CountDownLatch end_latch;public Runner(CountDownLatch start_latch, CountDownLatch end_latch) {this.start_latch = start_latch;this.end_latch = end_latch;}@Overridepublic void run() {try {start_latch.await(); //所有運動員都在準備狀態中,等待教練釋放開始門try {doWork(); //每個人跑步的時間不同end_latch.countDow n(); //跑完后,告訴教練跑完了} catch (InterruptedException e) {System.out.println("Interrupted Runner" + id);}} catch (InterruptedException e) {System.out.println("Interrupted Runner" + id);}}public void doWork() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));System.out.println(this + "completed");}@Overridepublic String toString() {return String.format("%1$-3d", id);} }class Coach implements Runnable {private final CountDownLatch start_latch;private final CountDownLatch end_latch;public Coach(CountDownLatch start_latch, CountDownLatch end_latch) {this.start_latch = start_latch;this.end_latch = end_latch;}@Overridepublic void run() {start_latch.countDown(); //教練釋放了開始門,運動員們都開始跑System.out.println("Coach say: Ready!!!! Go!!!!");try {end_latch.await(); //當結束門的count down減為0時,教練宣布所有人都跑完了。System.out.println("All runner passed the end point");} catch (InterruptedException ex) {System.out.println(this + " interrupted");}} }public class TestRunner {private static final int SIZE = 10;public static void main(String[] args) {ExecutorService exec = Executors.newCachedThreadPool();CountDownLatch startGate = new CountDownLatch(1);CountDownLatch endGate = new CountDownLatch(SIZE);for (int i = 0; i < SIZE; i++) {exec.execute(new Runner(startGate, endGate));}exec.execute(new Coach(startGate, endGate));exec.shutdown();} } 復制代碼CountDownLatch強調的是一個線程(或多個)需要等待另外的n個線程干完某件事情之后才能繼續執行。 上述例子,Coach線程是裁判,10個Runner是跑步的。運動員先準備,裁判喊跑,運動員才開始跑(這是第一次同步,對應startGate)。10個人誰跑到終點了,countdown一下,直到10個人全部到達,裁判喊停(這是第二次同步,對應endGate)。 最后運行結果如下:
Coach say: Ready!!!! Go!!!! 7 completed 9 completed 5 completed 8 completed 2 completed 0 completed 6 completed 4 completed 1 completed 3 completed All runner passed the end point
總結
以上是生活随笔為你收集整理的Java并发工具类(闭锁CountDownLatch)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 源码阅读分析 View的Touch事
- 下一篇: 从源码了解spring bean实例化过