Concurrency in Practiceでは、次の場合に揮発性変数を使用できると書かれています
変数への書き込みは、現在の値に依存しません。
したがって、共有された変更可能な variablea
があり、それに対して行うすべてのスレッドが go である場合a++
(それらは値を取得せず、単に++
) ます。
引用によると、アトミックでなくてvolatile
も作成できるはずですよね?a++
Concurrency in Practiceでは、次の場合に揮発性変数を使用できると書かれています
変数への書き込みは、現在の値に依存しません。
したがって、共有された変更可能な variablea
があり、それに対して行うすべてのスレッドが go である場合a++
(それらは値を取得せず、単に++
) ます。
引用によると、アトミックでなくてvolatile
も作成できるはずですよね?a++
いいえ、変数での使用++
はvolatile
スレッドセーフではありません。
a++
次と同等です。
int temp = a;
temp = temp + 1;
a = temp;
そのため、スレッドが読み取ってから別のスレッドが変更された後に への書き戻しa
が発生する可能性があるため、が揮発性であっても、スレッドセーフではありません。a
a++
a
AtomicInteger
スレッドセーフなアトミック インクリメントを実装する を使用できます。
a++ は a の値を読み取ります。
いいえ、この場合、揮発性変数を安全に使用することはできません。
- 揮発性は次のことを行います。
とマークされたフィールドはvolatile
、その値がすぐにメモリに書き込まれ、リタイア中にその値がメモリから読み取られます。
Threadでの値のキャッシュを防ぎます。
例えば:
a++
次のように解釈できます。
- aという名前のメモリ位置の値の読み取り。
-値を増やします。
-新たにインクリメントされた値を a という名前のメモリ位置に書き込みます。
上記のプロセス全体がnot
スレッドセーフになり++
、Java の (インクリメント演算子) はアトミックステートメントではなくなりました。
-キーワードを使用synchronized
することをお勧めします。使用したくない場合は、AtomicInteger
クラスを使用してください。
a++ はアトミックではなく、同等です
したがって、別のスレッドが邪魔になった場合でも、「更新を見逃す」可能性があります- volatile はそれを防ぐように設計されていません。それが「同期ブロック」と「ロック」の目的です。
a が揮発性であるという事実は、a がローカル キャッシュに格納されていないため、スレッド間での可視性にのみ影響します。そのため、異なるスレッド (異なるコアまたはプロセッサで実行されている) はすぐにその新しい値を「見る」ことができます。