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对象。