java多线程之CountDownLatch倒数闸门
生活随笔
收集整理的這篇文章主要介紹了
java多线程之CountDownLatch倒数闸门
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在多個線程進行協作時,一個常見的情景是一個線程需要等待另外的線程完成某些任務之后才能繼續進行.在這種情況下,可以使用CountDownLatch類,CountDownLatch類相當于多個線程等待開啟的一個閘門.只有在其他線程完成任務之后,閘門才會打開,等待的線程才能運行.在創建CountDownLatch類的對象是需要指定等待完成的任務數目.一個CountDownLatch.類的對象被執行任務的線程和等待任務完成的線程說共享.當執行任務的線程完成其任務時,調用countDown方法來使待完成的任務數量減1.等待任務完成的線程通過調用await方法進入阻塞狀態直到待完成的任務數量變為0.當所有任務都完成時,等待任務完成的線程會從await方法返回,可以繼續執行后繼的代碼.CountDownLatch類的對象的使用是一次性的.一旦待完成的任務數量變為0,再調用await方法就不再阻塞當前線程,而是立即返回.倒數閘門的使用示例: ?
| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 | import?java.util.concurrent.CountDownLatch;/**?*?create?at?11-9-17?*?*?@author?KETQI?*?@category?CountDownLatch主要起倒計時計數器作用,它主要有兩個方法await()和countDown()。?*?一旦某個線程調用await()方法,那么該線程就會阻塞,等待CountDownLatch計數器倒計時歸零,?*?需要注意的是盡管線程調用await()方法后會阻塞,?*?但是CountDownLatch允許別的線程調用countDown()方法,將計數器減一。?*?也就是說調用計時器的線程阻塞后,可以利用別的線程控制調用線程何時從新開始運行。?*?<p/>?*?該demo主要想要做的事就是:在主線程中創建N個子線程,讓支線程等待主線程將開關計數器startSignal打開。?*?而當主線程打開startSignal開關后,主線程要等待計數器doneSignal歸零,?*?而doneSignal計數器歸零依賴于每個支線程為主線程的計數器減一。?*?所以當主線程打開開關后,支線程才能運行完畢,而只有支線程全部運行完畢,才能打開主線程的計數器。?*?這樣整個程序才能走完?*/public?class?CountDownLatchDemo?{????public?static?final?int?N?=?5;????public?static?void?main(String[]?args)?throws?InterruptedException?{????????//?用于向工作線程發送啟動信號,由主線程調用????????CountDownLatch?startSignal?=?new?CountDownLatch(1);????????//?用于等待工作線程的結束信號,由子線程調用????????CountDownLatch?doneSignal?=?new?CountDownLatch(N);????????//?創建啟動線程????????System.out.println("開始創建并運行分支線程,且分支線程啟動startSignal計數器,等待主線程將startSignal計數器打開");????????for?(int?i?=?0;?i?<?N;?i++)?{????????????new?Thread(new?LatchWorker(startSignal,?doneSignal),?"t"?+?i).start();????????}????????//?主線程,遞減開始計數器,讓所有線程開始工作????????System.out.println("主線程"?+?Thread.currentThread().getName()?+?"將startSignal計數器打開");????????startSignal.countDown();????????//?主線程阻塞,等待所有線程完成????????System.out.println("主線程"?+?Thread.currentThread().getName()?+?"開始倒計時5個數");????????doneSignal.await();????????/**?????????*?為什么說運行到下一句,所有線程就全部運行完畢了呢。?因為主線程要倒計時5個數,?而產生的5個支線程在運行完畢前會將主線程的計數器減一,?????????*?所以如果所有支線程運行完畢了?,主線程才能繼續運行主線程的最后一個打印程序?????????*/????????System.out.println("所有線程運行完畢");????}}class?LatchWorker?implements?Runnable?{????//?用于等待啟動信號????private?final?CountDownLatch?startSignal;????//?用于發送結束信號????private?final?CountDownLatch?doneSignal;????LatchWorker(CountDownLatch?startSignal,?CountDownLatch?doneSignal)?{????????this.startSignal?=?startSignal;????????this.doneSignal?=?doneSignal;????}????public?void?run()?{????????try?{????????????//?一旦調用await()方法,該線程就會開始阻塞。知道計數器startSignal為0????????????System.out.println(Thread.currentThread().getName()?+?"?開始調用await()方法,等待計數器startSignal被主線程打開");????????????startSignal.await();????????????doWork();????????????System.out.println(Thread.currentThread().getName()?+?"?將主線程的計數器減一");????????????doneSignal.countDown();//?發送完成信號????????}?catch?(InterruptedException?ex)?{????????????ex.printStackTrace();????????}????}????void?doWork()?{????????System.out.println(Thread.currentThread().getName()?+?"?的計數器被打開,分支線程開始運行");????????try?{????????????Thread.sleep((long)?Math.random()?*?10000);????????}?catch?(InterruptedException?e)?{????????????e.printStackTrace();????????}????}} |
轉載于:https://blog.51cto.com/ketqi/687565
總結
以上是生活随笔為你收集整理的java多线程之CountDownLatch倒数闸门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《蚁人与黄蜂女:量子狂潮》内地总票房破亿
- 下一篇: 上海科研团队成功研发新型“生物墨水”,可