5

グラフ (ノードと頂点) 分割アルゴリズムに取り組んでいます。

複数のスレッドを使用して、グラフ内の特定の領域を識別しようとしています。

ノードがリージョンの一部として識別されたら、boolean markedノード オブジェクトの a を true に設定します。

複数のスレッドが同じノードを同時にマークしようとする可能性があります。

現在、同期を使用して、悪いことが起こらないようにしています。

ただし、すべてのスレッドが処理を終了した後まで、marked until の値を読み取ったことがないためです。同期コードを削除することはできますか? 言い換えれば、ブール変数に同時に書き込むときに何か問題が発生する可能性はありますか?

4

5 に答える 5

3

ブール変数に同時に書き込みを行うと、何か問題が発生する可能性はありますか?

はいといいえ。確かに、結果の値が何らかの形で破損することはありませんが、どの更新がフィールドに設定されるか、およびこれらの更新が他のスレッドによっていつ表示されるかについては、非決定論的になります。

このブール値を使用して決定を行うスレッドが複数ある場合は、ある時点でメモリ同期を提供する必要があります。フィールドを作成してもvolatileコストはほとんどかかりません。それがパフォーマンスの問題であるという証拠がない限り、フィールドを作成しないのvolatileは最適化が時期尚早である可能性が高くなります。比較して設定する場合は、AtomicBooleanをラップして のvolatile booleanような高レベルのメソッドを提供するをお勧めしますcompareAndSet(...)

于 2013-06-04T12:50:25.503 に答える
2

理論的には、いいえ、変数を宣言してもかまいませんvolatile。Volatile キーワードは、アトミック アクセスを保証します。

(ただし、書き込みの順序は重要ではなく、すべての書き込みの後にすべての読み取りが行われます。)

于 2013-06-04T12:49:00.127 に答える
2

いいえ、複数のスレッドが同じブール値に書き込みを行っても問題はありませんが、後で別のスレッドで値を (長い時間でも) 読み取る際に問題が発生する可能性があります。volatile問題を防ぐために、少なくとも変数をマークする必要があります。

于 2013-06-04T12:49:51.107 に答える
1

他の人が言っているように、複数のスレッドから同じ値に設定しようとしているだけであれば、ブール値が破損したり誤った値になるリスクはありません。

ただし、それも必要ない場合があります

すべてのスレッドが処理を終了した後まで、marked until の値を読み取ったことはありません。

明らかに、調整スレッドをワーカー スレッド ( Thread.join()CountdownLatch 、またはプリミティブ du jour など) と同期させるために何らかのバリアが必要であり、それらのほぼすべてがすでにすべてのマークを作成する事前発生関係を提供しています。コーディネーター スレッドに表示されます。

その単一の同期ポイントを持つことは、多数の volatile を読み取るよりもたまたま安価です (そして、私はそれを時期尚早の最適化とは呼びません。単に volatile の必要性をなくすだけです)。

于 2013-06-04T22:27:50.157 に答える
0

いいえ。その変数への書き込みの順序が重要でない場合。

于 2013-06-04T12:48:53.683 に答える