volatileは非原子操作を原子操作に変えることができますか?
1169 ワード
典型的な例は、クラスにlongタイプのメンバー変数があることです.カウンタ、価格など、メンバー変数が複数のスレッドにアクセスされることを知っている場合は、volatileに設定したほうがいいです.どうして?Javaでlongタイプ変数を読み込むのは原子ではないので、2つのステップに分ける必要があります.1つのスレッドがlong変数の値を変更している場合、別のスレッドはその値の半分(上位32ビット)しか見えない可能性があります.しかし、volatile型のlongまたはdouble変数の読み書きは原子である.以上がネットで検索した答えです.非ソース操作をソース操作に変更することはできないと思います.結局、i++という操作が存在し、本質的にvolatileは原子性を保証するのではなく、メモリの可視性を保証するしかありません.原理は参考になります.https://blog.csdn.net/T_luyang_T/article/details/103188314. しかも原子性も可視性も意味が違うので、この質問は質問法から問題があります.
可視性:共有変数に対するスレッドの変更は、他のスレッドによって原子性がタイムリーに表示されます.すなわち、再分割できません.マルチステップ操作に分けることはできません.たとえば、付与やreturnなどです.例えば「a=1;」や「return a;」のような操作はいずれも原子性を有する.「a+=b」のような操作は原子的ではなく、一部のJVMでは「a+=b」は、①aとbを取り出す②a+bを計算する③計算結果をメモリに書き込む3つのステップを経る場合があります
しかしSynchronizeは可視性と原子性を保証できる
最後のSynchronizedとVolatileの比較
可視性:共有変数に対するスレッドの変更は、他のスレッドによって原子性がタイムリーに表示されます.すなわち、再分割できません.マルチステップ操作に分けることはできません.たとえば、付与やreturnなどです.例えば「a=1;」や「return a;」のような操作はいずれも原子性を有する.「a+=b」のような操作は原子的ではなく、一部のJVMでは「a+=b」は、①aとbを取り出す②a+bを計算する③計算結果をメモリに書き込む3つのステップを経る場合があります
しかしSynchronizeは可視性と原子性を保証できる
最後のSynchronizedとVolatileの比較
1)Synchronized
2)Volatile
3)Volatile , Synchronized , (volatile ;synchronized 。)
4)volatile , synchronized ( ).
5)volatile , , synchronized 。
volatile JVM , , , 。 n=n+1,n++ ,volatile , synchronized ( ) 。