2017-05-19 33 views
-1

以下是有關如何防止競爭條件的答案。 What is a race condition?不可變對象如何有助於防止競爭條件

最好的事情是創建無副作用和無狀態 功能,使用immutables儘可能。但這並不總是 可能。因此,使用java.util.concurrent.atomic,併發數據 結構,適當的同步和基於角色的併發將幫助 。

這個答案說盡可能地使用immutables。我很困惑不變的對象如何防止競爭條件。

+0

如果一個對象是不可變的,那麼多少個線程訪問它並不重要。 –

+4

如果您無法修改內容,則不能進行併發修改。 – user2357112

回答

1

只有當至少有一個線程被允許寫/改變實例的狀態時纔會出現競爭條件。 不可變實例只讀,它們的狀態不能被改變,因此,所有線程只讀的對象的狀態,並且看到相同的值(一個或多個)

0

data race時發生「兩個或多個線程...同時訪問相同的內存位置,並且至少有一個訪問用於寫入,並且這些線程不使用任何排他鎖來控制對該內存的訪問。「

如果數據不可變,就不會有數據競爭,因爲可能沒有寫入權限。

另外,Java Memory Model guarantees

一旦對象被構造中,分配給在構造最終字段中的值將是可見的所有其它線程不同步。

0

當計算結果取決於評估表達式和語句的順序時,會出現競爭條件。

如果對錶達式和語句的評估改變狀態,產生副作用,結果可能會有所不同。

如果代碼中的所有內容都是不可變的,那麼在對錶達式和語句進行評估時,不會改變狀態,也不會產生副作用。因此評估順序不會影響最終結果。

考慮下面的代碼:

Map<String, Integer> map = Collections.singletonMap("key", 0); 

public void increment() { 
    int val = map.get("key); 
    map.put("key", val + 1); 
} 

如果兩個線程執行方法increment()的每個語句同時,同時讀同一價值0兩者放在同一增加值1map。因此結果將是1

如果兩個線程(偶然)將執行所有語句連續一個線程會讀取值0,並把價值1而其他線程會讀取值1,把價值2

現在,如果地圖將是不可改變的,兩個線程將執行以下方法:

public void logMap() { 
    System.out.println("Key has value " + map.get("key")); 
} 

結果將始終是相同的,因爲沒有副作用(除了由所做的更改System.out.println)影響計算。