countdownlatch 使用說明,供大家參考,具體內容如下
countdownlatch是一種java.util.concurrent包下一個同步工具類,它允許一個或多個線程等待直到在其他線程中一組操作執行完成。
countdownlatch的用法非常簡單,下面的例子也是我在網上看到的,十分貼切,這里就貼出來
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
public class test { public static void main(string[] args) { countdownlatch begin = new countdownlatch( 1 ); countdownlatch end = new countdownlatch( 2 ); for ( int i= 0 ; i< 2 ; i++){ thread thread = new thread( new player(begin,end)); thread.start(); } try { system.out.println( "the race begin" ); begin.countdown(); end.await(); system.out.println( "the race end" ); } catch (exception e){ e.printstacktrace(); } } } /** * 選手 */ class player implements runnable{ private countdownlatch begin; private countdownlatch end; player(countdownlatch begin,countdownlatch end){ this .begin = begin; this .end = end; } public void run() { try { begin.await(); system.out.println(thread.currentthread().getname() + " arrived !" );; end.countdown(); } catch (interruptedexception e) { e.printstacktrace(); } } } |
下面是運行結果
可以看到 通過countdownlatch 的使用 我們控制了線程的執行順序。
在上面代碼中,我們使用到await()方法 和 countdown() 方法 。我們驗證一下它們各自的作用。
首先 驗證await() 方法。將main方法中的end.await() 注釋掉,下面是注釋掉后的運行結果
可以看到主線程沒有等待代表選手的線程結束,直接宣布比賽結束了!剛開始就結束的比賽- -
這里可以看出,await() 方法具有阻塞作用
其次 我們來驗證countdown方法,將代表選手線程中的end.countdown() 進行注釋,下面是運行結果
程序一直在運行,所有選手都已經到了終點,但是裁判就是不宣傳比賽結束,他在等什么呢?
我們猜測countdown() 方法具有喚醒阻塞線程的作用。
那我們也許會問,既然有喚醒阻塞線程的作用,那么我們只調用一次countdown() 方法不就是可以喚醒被阻塞的主線程了嗎?
我們試一下,取消上面coutdown()的注釋,再次創建一個選手,代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
class player2 implements runnable{ private countdownlatch begin; private countdownlatch end; player2(countdownlatch begin,countdownlatch end){ this .begin = begin; this .end = end; } public void run() { try { begin.await(); system.out.println(thread.currentthread().getname() + " arrived !" ); // end.countdown(); } catch (interruptedexception e) { e.printstacktrace(); } } } |
main 方法也修改如下,創建了兩個不同的選手
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public static void main(string[] args) { countdownlatch begin = new countdownlatch( 1 ); countdownlatch end = new countdownlatch( 2 ); thread thread = new thread( new player(begin, end)); thread.start(); thread thread2 = new thread( new player2(begin, end)); thread2.start(); try { system.out.println( "the race begin" ); begin.countdown(); end.await(); system.out.println( "the race end" ); } catch (exception e) { e.printstacktrace(); } } |
運行一下,下面是結果
主程序一直阻塞,沒有被喚醒,裁判上廁所上得有點久啊!
這樣看來countdown() 并不是直接喚醒線程,有點像一個計數器,倒計時的那種。
查看api文檔,果然,我們在構造函數中添加了參數2,就需要調用 2 次 countdown() 才能將 end.await() 阻塞的線程喚醒。
1
|
countdownlatch end = new countdownlatch( 2 ); |
總結一下,
1、countdownlatch end = new countdownlatch(n); //構造對象時候 需要傳入參數n
2、end.await() 能夠阻塞線程 直到調用n次end.countdown() 方法才釋放線程
3、end.countdown() 可以在多個線程中調用 計算調用次數是所有線程調用次數的總和
下一篇博客,我將從源碼層面說明 countdownlatch 的工作原理。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/cuglkb/p/8572239.html