2012-06-30 18 views

答えて

6

私にとってデータレースはすべてレースコンディションのサブセットです。データ競合は、2つ以上のスレッドが適切なロックなしに同じメモリにアクセスしたときに発生し、予期しない値につながります(少なくとも1つのスレッドが書き込みを行っている場合)。レース条件の用語は、一般に、例えば、スレッドのスケジューリング(およびロック機構の不適切な使用)の競合により時折デッドロックするスレッド。

16

ウィキペディアによれば、「競合状態」という用語は、最初の電子論理ゲートの時代から使用されていました。 Javaのコンテキストでは、競合状態は、ファイル、ネットワーク接続、スレッドプールからのスレッドなどの任意のリソースに関係する可能性があります。

用語「データ競合」は、 JLSによって。

最も興味深いケースは、データレースに非常によく似ている競合状態であるが、それでもこの単純な例のように、一つではない:iは揮発性である

class Race { 
    static volatile int i; 
    static int uniqueInt() { return i++; } 
} 

ので、データが存在しませんレース;しかし、プログラムの正確さの観点からは、2つの操作の非アトミック性のために競合状態が存在する:iを読み、i+1と書く。複数のスレッドがuniqueIntから同じ値を受け取ることがあります。

+0

を、あなたは 'データrace'が実際JLSに何を意味するのか説明し、あなたの答えに一列にドロップすることができますか? – Geek

+0

@geek "JLS"という単語は、JLSの関連セクションへのハイパーリンクです。 –

74

いいえ、それらは同じものではありません。彼らはお互いのサブセットではありません。彼らはまた、お互いに必要でも十分な条件でもありません。

データ競争の定義はかなり明確であるため、その発見は自動化することができます。データ競合は、異なるスレッドからの2つの命令が同じメモリ位置にアクセスしたときに発生し、これらのアクセスのうちの少なくとも1つは書き込みであり、これらのアクセスのうちのいずれかを指定する同期はありません。

競合状態は意味エラーです。誤ったプログラム動作につながるイベントのタイミングまたは順序に発生する欠陥です。多くの競合状態はデータ競争によって引き起こされる可能性がありますが、これは必須ではありません。

Xは共有変数である次の簡単な例を考える:この例では

Thread 1 Thread 2 

lock(l)  lock(l) 
x=1   x=2 
unlock(l) unlock(l) 

を、スレッド1および2からXへの書き込みは、したがって、それらは常に強制いくつかの順序で起こっている、ロックによって保護されてい実行時にロックが取得される順序によって異なります。つまり、書き込みのアトミック性は壊れません。任意の実行における2つの書き込みの間には常に関係が生じる。私たちはどちらの書き込みが先験的に先行するのか分かりません。

ロックはこれを提供することができないため、書き込み間には固定順序がありません。プログラムの正確性が損なわれた場合、スレッド2のxへの書き込みに続いてスレッド1のxへの書き込みが続くと、技術的にはデータ競合はないものの、競合状態が存在すると言います。

データ競合より競合状態を検出する方がずっと便利です。しかし、これは達成することも非常に困難です。

逆の例を構築することも簡単です。 Thisブログ投稿も簡単な銀行取引の例で、違いをよく説明しています。

+0

+1の前に「起こる前に」 – zencv

+0

"データ競争(...)これらのアクセスの間に特定の順序を強制する同期はありません。 私は少し混乱しています。あなたの例では、両方の注文(= 1、= 2、またはその逆)で操作が行われる可能性があります。なぜデータ競争ではないのですか? – josinalvo

+2

@josinalvo:データ競争の技術的定義の成果物です。重要なポイントは、2つのアクセスの間に、ロック解除とロック取得(可能な注文のいずれか)があることです。定義上、ロック解除とロック獲得は2つのアクセスの間に順序を確立し、したがってデータ競合は存在しません。 –

2

いいえ、それらは異なっています&どちらもサブセットのいずれかまたはその逆です。

用語競合状態は、多くの場合、同期が共有非最終フィールドへのすべての アクセスを調整するために使用されていない場合に発生する関連語データ レースと混同です。 スレッドが別のスレッドによって次に読み取られる可能性のある変数を書き込むか、または が別のスレッドによって最後に書き込まれた可能性のある変数を読み取ると、データ競合が発生するリスクがあります。 両方のスレッドが同期を使用しない場合、データ競合のあるコードは、 Javaメモリモデルの下で有用な定義されたセマンティクスを持っていません。すべてのレースがデータレースであるわけではなく、すべてのデータレースがレースコンディション( )であるわけではありませんが、どちらも同時プログラムが予期しないエラーで失敗する可能性があります( )。優秀な本からの引用

- ジョシュア・ブロック&社実践のJava並行処理