2017-05-19 21 views
-1

以下は、競合状態を防止する方法の答えです。 What is a race condition?不変オブジェクトが競合状態を防止する方法

最善のことは可能な限り、無料とステートレス 機能に利用immutablesを副作用を作成することです。しかし、必ずしもそうであるとは限りません 。したがって、java.util.concurrent.atomicを使用すると、同時データ の構造、適切な同期、およびアクターベースの同時実行性は になります。

この回答では、できるだけimmutablesを使用しています。私は不変なオブジェクトが競合状態をいかに防ぐかについて混乱しています。

+0

オブジェクトが不変の場合、アクセスするスレッドの数は関係ありません。 –

+4

変更ができない場合は、同時に変更することはできません。 – user2357112

答えて

1

競合状態は、少なくとも1つのスレッドがインスタンスの状態の書き込み/変更を許可されている場合にのみ発生します。 不変インスタンスは読み取り専用、それらの状態は、したがって、すべてのスレッドのみオブジェクトの状態を読み取り、同じ値(複数可)を参照し、を変更することはできませんされ

0

data race場合「とは、2つ以上のスレッドを発生...同じメモリ位置に同時にアクセスし、少なくとも1つのアクセスは書き込み用であり、スレッドはそのメモリへのアクセスを制御するために排他ロックを使用していません。

書き込みアクセスがない可能性があるため、データが不変の場合、データ競合は発生しません。

また、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); 
} 

2もしスレッドが両方とも同じ値0を読んで、両方がmapに同じインクリメント値1を入れ、同時に方法increment()のすべての文を実行します。したがって、結果は1になります。

(偶然に)両方のスレッドが他のスレッドが値1を読み、値2を置くだろうが値0を読み、値1を置く連続1つのスレッドすべての文を実行したい場合。

今マップは不変であろうと両スレッドは、以下の方法を実行するかどう:によって行われた変更のほかにない副作用が(存在しないため

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

の結果は常に、同じですSystem.out.println)。

関連する問題