以下是有關如何防止競爭條件的答案。 What is a race condition?不可變對象如何有助於防止競爭條件
最好的事情是創建無副作用和無狀態 功能,使用immutables儘可能。但這並不總是 可能。因此,使用java.util.concurrent.atomic,併發數據 結構,適當的同步和基於角色的併發將幫助 。
這個答案說盡可能地使用immutables。我很困惑不變的對象如何防止競爭條件。
以下是有關如何防止競爭條件的答案。 What is a race condition?不可變對象如何有助於防止競爭條件
最好的事情是創建無副作用和無狀態 功能,使用immutables儘可能。但這並不總是 可能。因此,使用java.util.concurrent.atomic,併發數據 結構,適當的同步和基於角色的併發將幫助 。
這個答案說盡可能地使用immutables。我很困惑不變的對象如何防止競爭條件。
只有當至少有一個線程被允許寫/改變實例的狀態時纔會出現競爭條件。 不可變實例只讀,它們的狀態不能被改變,因此,所有線程只讀的對象的狀態,並且看到相同的值(一個或多個)
甲data race時發生「兩個或多個線程...同時訪問相同的內存位置,並且至少有一個訪問用於寫入,並且這些線程不使用任何排他鎖來控制對該內存的訪問。「
如果數據不可變,就不會有數據競爭,因爲可能沒有寫入權限。
另外,Java Memory Model guarantees:
一旦對象被構造中,分配給在構造最終字段中的值將是可見的所有其它線程不同步。
當計算結果取決於評估表達式和語句的順序時,會出現競爭條件。
如果對錶達式和語句的評估改變狀態,產生副作用,結果可能會有所不同。
如果代碼中的所有內容都是不可變的,那麼在對錶達式和語句進行評估時,不會改變狀態,也不會產生副作用。因此評估順序不會影響最終結果。
考慮下面的代碼:
Map<String, Integer> map = Collections.singletonMap("key", 0);
public void increment() {
int val = map.get("key);
map.put("key", val + 1);
}
如果兩個線程執行方法increment()
的每個語句同時,同時讀同一價值0
兩者放在同一增加值1
到map
。因此結果將是1
。
如果兩個線程(偶然)將執行所有語句連續一個線程會讀取值0
,並把價值1
而其他線程會讀取值1
,把價值2
。
現在,如果地圖將是不可改變的,兩個線程將執行以下方法:
public void logMap() {
System.out.println("Key has value " + map.get("key"));
}
結果將始終是相同的,因爲沒有副作用(除了由所做的更改System.out.println)影響計算。
如果一個對象是不可變的,那麼多少個線程訪問它並不重要。 –
如果您無法修改內容,則不能進行併發修改。 – user2357112