天天看点

Java并发新构件之CounDownLatch

    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 &lt; </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 &lt; 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对象。