countdownlatch 使用說明,供大家參考,具體內(nèi)容如下
countdownlatch是一種java.util.concurrent包下一個同步工具類,它允許一個或多個線程等待直到在其他線程中一組操作執(zhí)行完成。
countdownlatch的用法非常簡單,下面的例子也是我在網(wǎng)上看到的,十分貼切,這里就貼出來
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(); } } } |
下面是運行結(jié)果
可以看到 通過countdownlatch 的使用 我們控制了線程的執(zhí)行順序。
在上面代碼中,我們使用到await()方法 和 countdown() 方法 。我們驗證一下它們各自的作用。
首先 驗證await() 方法。將main方法中的end.await() 注釋掉,下面是注釋掉后的運行結(jié)果
可以看到主線程沒有等待代表選手的線程結(jié)束,直接宣布比賽結(jié)束了!剛開始就結(jié)束的比賽- -
這里可以看出,await() 方法具有阻塞作用
其次 我們來驗證countdown方法,將代表選手線程中的end.countdown() 進行注釋,下面是運行結(jié)果
程序一直在運行,所有選手都已經(jīng)到了終點,但是裁判就是不宣傳比賽結(jié)束,他在等什么呢?
我們猜測countdown() 方法具有喚醒阻塞線程的作用。
那我們也許會問,既然有喚醒阻塞線程的作用,那么我們只調(diào)用一次countdown() 方法不就是可以喚醒被阻塞的主線程了嗎?
我們試一下,取消上面coutdown()的注釋,再次創(chuàng)建一個選手,代碼如下
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 方法也修改如下,創(chuàng)建了兩個不同的選手
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(); } } |
運行一下,下面是結(jié)果
主程序一直阻塞,沒有被喚醒,裁判上廁所上得有點久??!
這樣看來countdown() 并不是直接喚醒線程,有點像一個計數(shù)器,倒計時的那種。
查看api文檔,果然,我們在構(gòu)造函數(shù)中添加了參數(shù)2,就需要調(diào)用 2 次 countdown() 才能將 end.await() 阻塞的線程喚醒。
1
|
countdownlatch end = new countdownlatch( 2 ); |
總結(jié)一下,
1、countdownlatch end = new countdownlatch(n); //構(gòu)造對象時候 需要傳入?yún)?shù)n
2、end.await() 能夠阻塞線程 直到調(diào)用n次end.countdown() 方法才釋放線程
3、end.countdown() 可以在多個線程中調(diào)用 計算調(diào)用次數(shù)是所有線程調(diào)用次數(shù)的總和
下一篇博客,我將從源碼層面說明 countdownlatch 的工作原理。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://www.cnblogs.com/cuglkb/p/8572239.html