天天看點

java并發程式設計實踐學習(2)--對象的組合

先驗條件(Precondition):某些方法包含基于狀态的先驗條件。例如,不能從空隊列中移除一個元素,在删除元素前隊列必須處于非空狀态。基于狀态的先驗條件的操作成為依賴狀态操作。

在單線程中,如果某操作無法滿足先驗條件,就隻能失敗,但在并發程式中先驗條件可能會由于其他線程執行的操作而變成真。

java中等待某個條件為真的各種内置機制(包括等待和通知機制)都與内置加鎖緊密關聯。

所有權和封裝性總是相關聯的:對象封裝它擁有的所有權,對象對它的封裝的狀态擁有所有權。

釋出了某個可變對象的引用,那就不再擁有獨占的控制權。

容器類通常表現出一種“所有權分離”的形式。

<a></a>

在設計線程安全類的過程中,需要包含以下三個基本要素:

找出構成對象狀态的所有變量 找出限制狀态變量的不可變性條件 建立對象狀态的并發通路管理政策

可以将共享資源委托給一個線程安全的類。比如ConcurrentHashMap,copyOnWriteArrayList.

如果一個類時由多個獨立且線程安全的狀态變量組成,并且在所有的操作中都不包含無效狀态轉換,那麼可以将線程安全性委托給底層狀态變量。

下面是一個監控車輛位置的執行個體。其中Point是線程安全不可變的類。

<a href="http://www.cnblogs.com/woshimrf/p/5242029.html#" target="_blank">+ View Code</a>

  如果一個狀态變量是線程安全的,并且沒有任何不變性條件來限制它的值,在變量的操作上也不存在任何不允許的狀态轉換,那麼就可以安全地釋出這個變量。

同樣是車輛追蹤,我想要擷取位置,還可以修改位置,安全性問題可以交給底層SafePoint:

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

<code>/**</code>

<code> </code><code>* 線程安全且可變的Point類</code>

<code> </code><code>*/</code>

<code>@ThreadSafe</code>

<code>class</code> <code>SafePoint{</code>

<code>    </code><code>@GuardedBy</code><code>(</code><code>"this"</code><code>) </code><code>private</code> <code>int</code> <code>x,y;</code>

<code>    </code><code>private</code> <code>SafePoint(</code><code>int</code><code>[] a){</code>

<code>        </code><code>this</code><code>(a[</code><code>0</code><code>],a[</code><code>1</code><code>]);</code>

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

<code>    </code><code>public</code> <code>SafePoint(SafePoint p){</code>

<code>        </code><code>this</code><code>(p.get());</code>

<code>    </code><code>public</code> <code>SafePoint(</code><code>int</code> <code>x,</code><code>int</code> <code>y){</code>

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

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

<code>    </code><code>public</code> <code>synchronized</code> <code>int</code><code>[] get(){</code>

<code>        </code><code>return</code> <code>new</code> <code>int</code><code>[] {x,y};</code>

<code>    </code><code>public</code> <code>synchronized</code> <code>void</code> <code>set(</code><code>int</code> <code>x,</code><code>int</code> <code>y){</code>

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

<code>}</code>

<code> </code><code>* 安全釋出底層狀态的車輛追蹤器</code>

<code>class</code> <code>PublishingVehicleTracker{</code>

<code>    </code><code>private</code> <code>final</code> <code>Map&lt;String,SafePoint&gt; locations;</code>

<code>    </code><code>private</code> <code>final</code> <code>Map&lt;String,SafePoint&gt; unmodifiableMap;</code>

<code>    </code><code>PublishingVehicleTracker(Map&lt;String, SafePoint&gt; locations, Map&lt;String, SafePoint&gt; unmodifiableMap) {</code>

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

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

<code>    </code><code>public</code> <code>Map&lt;String,SafePoint&gt; getLocations(){</code>

<code>        </code><code>return</code> <code>unmodifiableMap;</code>

<code>    </code><code>public</code> <code>SafePoint getLocation(String id){</code>

<code>        </code><code>return</code> <code>locations.get(id);</code>

<code>    </code><code>public</code> <code>void</code> <code>setLocation(String id,</code><code>int</code> <code>x,</code><code>int</code> <code>y){</code>

<code>        </code><code>if</code> <code>(!locations.containsKey(id))</code>

<code>            </code><code>throw</code> <code>new</code> <code>IllegalArgumentException(</code><code>"invalid vehicle name:"</code><code>+id);</code>

<code>        </code><code>locations.get(id).set(x,y);</code>

在文檔中說明客戶代碼需要了解的線程安全性保證,以及代碼維護人員需要了解的同步政策。

synchronized,volatile或者任何一個線程安全類都對應于某種同步政策,用于在并發通路時確定資料的完整性。一定要在忘記之前記錄下來。

可以使用@GuardedBy("this")或者别的來注釋鎖。

本文轉自Ryan.Miao部落格園部落格,原文連結:http://www.cnblogs.com/woshimrf/p/5242029.html,如需轉載請自行聯系原作者