countdownlatch主要用于同步一個或多個任務,強制它們等待由其他任務執行的一組操作完成。
你可以向countdownlatch對象設定一個初始計數值,任何在這個對象上調用wait()的方法都将阻塞,直到這個計數值達到0.其他任務在結束其工作時,可以在該對象上調用countdown()來減小這個計數值,你可以通過調用getcount()方法來擷取目前的計數值。countdownlatch被設計為隻觸發一次,計數值不能被重置。如果你需要能夠重置計數值的版本,則可以使用cyclicbarrier。
調用countdown()的任務在産生這個調用時并沒有阻塞,隻有對await()的調用會被阻塞,直到計數值到達0。
countdownlatch的典型用法是将一個程式分為n個互相獨立的可解決人物,并建立值為0的countdownlatch。當每個任務完成是,都會在這個鎖存器上調用countdown()。等待問題被解決的任務在這個鎖存器上調用await(),将它們自己鎖住,直到鎖存器計數結束。下面是示範這種技術的一個架構示例:
<a href="http://my.oschina.net/itblog/blog/516282#">?</a>
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<code>import</code> <code>java.util.random;</code>
<code>import</code> <code>java.util.concurrent.countdownlatch;</code>
<code>import</code> <code>java.util.concurrent.delayqueue;</code>
<code>import</code> <code>java.util.concurrent.executorservice;</code>
<code>import</code> <code>java.util.concurrent.executors;</code>
<code>import</code> <code>java.util.concurrent.timeunit;</code>
<code>class</code> <code>taskportion </code><code>implements</code> <code>runnable {</code>
<code> </code><code>private</code> <code>static</code> <code>int</code> <code>counter = </code><code>0</code><code>;</code>
<code> </code><code>private</code> <code>final</code> <code>int</code> <code>id = counter++;</code>
<code> </code><code>private</code> <code>static</code> <code>random random = </code><code>new</code> <code>random();</code>
<code> </code><code>private</code> <code>final</code> <code>countdownlatch latch;</code>
<code> </code><code>public</code> <code>taskportion(countdownlatch latch) {</code>
<code> </code><code>this</code><code>.latch = latch;</code>
<code> </code><code>}</code>
<code> </code><code>@override</code>
<code> </code><code>public</code> <code>void</code> <code>run() {</code>
<code> </code><code>try</code> <code>{</code>
<code> </code><code>dowork();</code>
<code> </code><code>latch.countdown();</code><code>//普通任務執行完後,調用countdown()方法,減少count的值</code>
<code> </code><code>system.out.println(</code><code>this</code> <code>+ </code><code>" completed. count="</code> <code>+ latch.getcount());</code>
<code> </code><code>} </code><code>catch</code> <code>(interruptedexception e) {</code>
<code> </code>
<code> </code><code>}</code>
<code> </code>
<code> </code><code>public</code> <code>void</code> <code>dowork() </code><code>throws</code> <code>interruptedexception {</code>
<code> </code><code>timeunit.milliseconds.sleep(random.nextint(</code><code>2000</code><code>));</code>
<code> </code><code>public</code> <code>string tostring() {</code>
<code> </code><code>return</code> <code>string.format(</code><code>"%1$-2d "</code><code>, id);</code>
<code>}</code>
<code>class</code> <code>waitingtask </code><code>implements</code> <code>runnable {</code>
<code> </code><code>public</code> <code>waitingtask(countdownlatch latch) {</code>
<code> </code><code>//這些後續任務需要等到之前的任務都執行完成後才能執行,即count=0時</code>
<code> </code><code>latch.await();</code>
<code> </code><code>system.out.println(</code><code>"latch barrier passed for "</code> <code>+ </code><code>this</code><code>);</code>
<code> </code><code>system.out.println(</code><code>this</code> <code>+ </code><code>" interrupted."</code><code>);</code>
<code> </code><code>return</code> <code>string.format(</code><code>"waitingtask %1$-2d "</code><code>, id);</code>
<code>public</code> <code>class</code> <code>countdownlatchdemo {</code>
<code> </code><code>static</code> <code>final</code> <code>int</code> <code>size = </code><code>10</code><code>;</code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) {</code>
<code> </code><code>countdownlatch latch = </code><code>new</code> <code>countdownlatch(size);</code>
<code> </code><code>executorservice exec = executors.newcachedthreadpool();</code>
<code> </code><code>//10個waitingtask</code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i < </code><code>5</code><code>; i++) {</code>
<code> </code><code>exec.execute(</code><code>new</code> <code>waitingtask(latch));</code>
<code> </code><code>//100個任務,這100個任務要先執行才會執行waitingtask</code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i < size; i++) {</code>
<code> </code><code>exec.execute(</code><code>new</code> <code>taskportion(latch));</code>
<code> </code><code>system.out.println(</code><code>"launched all tasks."</code><code>);</code>
<code> </code><code>exec.shutdown();</code><code>//當所有的任務都結束時,關閉exec</code>
執行結果(可能的結果):
<code>launched all tasks.</code>
<code>4</code> <code>completed. count=</code><code>9</code>
<code>6</code> <code>completed. count=</code><code>8</code>
<code>3</code> <code>completed. count=</code><code>7</code>
<code>0</code> <code>completed. count=</code><code>6</code>
<code>2</code> <code>completed. count=</code><code>5</code>
<code>1</code> <code>completed. count=</code><code>4</code>
<code>5</code> <code>completed. count=</code><code>3</code>
<code>7</code> <code>completed. count=</code><code>2</code>
<code>9</code> <code>completed. count=</code><code>1</code>
<code>8</code> <code>completed. count=</code><code>0</code>
<code>latch barrier passed </code><code>for</code> <code>waitingtask </code><code>0</code>
<code>latch barrier passed </code><code>for</code> <code>waitingtask </code><code>2</code>
<code>latch barrier passed </code><code>for</code> <code>waitingtask </code><code>1</code>
<code>latch barrier passed </code><code>for</code> <code>waitingtask </code><code>3</code>
<code>latch barrier passed </code><code>for</code> <code>waitingtask </code><code>4</code>
從結果中可以看到,所有的waitingtask都是在所有的taskportion執行完成之後執行的。
taskportion将随機的休眠一段時間,以模拟這部分工作的完成。而waitingtask表示系統中必須等待的部分,它要等到問題的初始部分完成後才能執行。注意:所有任務都使用了在main()中定義的同一個countdownlatch對象。