先驗條件(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<String,SafePoint> locations;</code>
<code> </code><code>private</code> <code>final</code> <code>Map<String,SafePoint> unmodifiableMap;</code>
<code> </code><code>PublishingVehicleTracker(Map<String, SafePoint> locations, Map<String, SafePoint> 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<String,SafePoint> 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,如需轉載請自行聯系原作者