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の比較
1)Synchronized              
2)Volatile         
3)Volatile     , Synchronized    ,       (volatile         ;synchronized          。)
4)volatile             , synchronized             (          ).
5)volatile      ,      , synchronized           。
  volatile      JVM                ,   ,         ,         。  n=n+1,n++    ,volatile      ,     synchronized       (   )   。