天天看點

Java并發(三)使用顯式的Lock和Condition對象

    下面是waxonmatic.java的重寫版本,它包含了一個condition,用來在waitforwaxing()或waitforbuffing()内部挂起一個任務:

<a href="http://my.oschina.net/itblog/blog/515687#">?</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

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

<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>import</code> <code>java.util.concurrent.locks.condition;</code>

<code>import</code> <code>java.util.concurrent.locks.lock;</code>

<code>import</code> <code>java.util.concurrent.locks.reentrantlock;</code>

<code>class</code> <code>car {</code>

<code>    </code><code>private</code> <code>lock lock = </code><code>new</code> <code>reentrantlock();</code>

<code>    </code><code>private</code> <code>condition condition = lock.newcondition();</code>

<code>    </code><code>private</code> <code>boolean</code> <code>waxon = </code><code>false</code><code>;</code><code>//是否上蠟</code>

<code>    </code><code>//上蠟</code>

<code>    </code><code>public</code> <code>void</code> <code>waxed() {</code>

<code>        </code><code>lock.lock();</code>

<code>        </code><code>try</code> <code>{</code>

<code>            </code><code>waxon = </code><code>true</code><code>;</code>

<code>            </code><code>condition.signalall();</code>

<code>        </code><code>} </code><code>finally</code> <code>{</code>

<code>            </code><code>lock.unlock();</code>

<code>        </code><code>}</code>

<code>    </code><code>}</code>

<code>    </code><code>//抛光</code>

<code>    </code><code>public</code> <code>void</code> <code>buffed() {</code>

<code>            </code><code>waxon = </code><code>false</code><code>;</code>

<code>    </code><code>//等待上蠟</code>

<code>    </code><code>public</code> <code>void</code> <code>waitforwaxing() </code><code>throws</code> <code>interruptedexception {</code>

<code>            </code><code>while</code><code>(waxon == </code><code>false</code><code>) {</code>

<code>                </code><code>condition.await();</code>

<code>            </code><code>}</code>

<code>    </code><code>//等待抛光</code>

<code>    </code><code>public</code> <code>void</code> <code>waitforbuffing() </code><code>throws</code> <code>interruptedexception {</code>

<code>            </code><code>while</code><code>(waxon == </code><code>true</code><code>) {</code>

<code>        </code> 

<code>}</code>

<code>class</code> <code>waxontask </code><code>implements</code> <code>runnable {</code>

<code>    </code><code>private</code> <code>car car;</code>

<code>    </code><code>private</code> <code>string name;</code>

<code>    </code><code>public</code> <code>waxontask(string name, car car) {</code>

<code>        </code><code>this</code><code>.name = name;</code>

<code>        </code><code>this</code><code>.car = car;</code>

<code>    </code><code>@override</code>

<code>    </code><code>public</code> <code>void</code> <code>run() {</code>

<code>            </code><code>while</code><code>(!thread.interrupted()) {</code>

<code>                </code><code>system.out.println(</code><code>"["</code> <code>+ name + </code><code>"] is wax on!"</code><code>);</code><code>//正在上蠟</code>

<code>                </code><code>timeunit.milliseconds.sleep(</code><code>300</code><code>);</code>

<code>                </code><code>car.waxed();</code><code>//上蠟完成</code>

<code>                </code><code>car.waitforbuffing();</code><code>//等待抛光</code>

<code>        </code><code>} </code><code>catch</code> <code>(interruptedexception e) {</code>

<code>            </code><code>system.out.println(</code><code>"["</code> <code>+ name + </code><code>"] exiting waxontask via interrupt."</code><code>);</code>

<code>class</code> <code>bufftask </code><code>implements</code> <code>runnable {</code>

<code>    </code><code>public</code> <code>bufftask(string name, car car) {</code>

<code>                </code><code>car.waitforwaxing();</code><code>//等待上蠟</code>

<code>                </code><code>system.out.println(</code><code>"["</code> <code>+ name + </code><code>"] buffing..."</code><code>);</code><code>//正在抛光</code>

<code>                </code><code>car.buffed();</code><code>//抛光完成</code>

<code>            </code><code>system.out.println(</code><code>"["</code> <code>+ name + </code><code>"] exiting bufftask via interrupt."</code><code>);</code>

<code>public</code> <code>class</code> <code>waxomatic2 {</code>

<code>    </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) </code><code>throws</code> <code>exception {</code>

<code>        </code><code>car car = </code><code>new</code> <code>car();</code>

<code>        </code><code>executorservice exec = executors.newcachedthreadpool();</code>

<code>        </code><code>//上蠟</code>

<code>        </code><code>exec.execute(</code><code>new</code> <code>waxontask(</code><code>"waxx"</code><code>, car));</code>

<code>        </code><code>//抛光</code>

<code>        </code><code>exec.execute(</code><code>new</code> <code>bufftask(</code><code>"buff"</code><code>, car));</code>

<code>        </code><code>//運作一段時間,停止executorservice</code>

<code>        </code><code>timeunit.seconds.sleep(</code><code>3</code><code>);</code>

<code>        </code><code>exec.shutdownnow();</code>

執行結果:

<code>[waxx] is wax on!</code>

<code>[buff] buffing...</code>

<code>[buff] exiting bufftask via interrupt.</code>

<code>[waxx] exiting waxontask via interrupt.</code>

    從代碼中可以看到,car的構造器中,單個的lock将産生一個condition對象,這個對象被用來管理任務之間的通信。但是,這個condition對象不包含任何有關處理狀态的資訊,是以你需要管理額外的表示處理狀态的資訊,即boolean waxon。

    注意:每個lock()的調用都必須緊跟一個try-finally子句,用來保證在所有情況下都可以釋放鎖。在使用内建版本時,任務在可以調用await(),signal()或signalall()之前,必須擁有這個鎖。

    另外還需要注意的是,這個解決方案比之前一個更加複雜,在本例中這種複雜性并未使你收獲更多。lock和condition對象隻有在更加困難的多線程問題中才是必需的。