[Java][C]JavaのvolatileとCのvolatileSGソフトウェア開発ブログ株式会社エス・ジーの社員が日々のソフトウェア開発で学んだ技術を公開していくブログです。JavaJavaでvolatileを使う場面は限られてくるけど、マルチスレッドの処理でパフォーマンスが問題になってくるようなときに使う。通常のロックでは処理が重くなってしまうような場合だね。読み込み側が1人しかいなくて、素直にAtomicInteger使えみたいな例になってるけど。これはvolatileフィールドの以下のような性質を使っている。long変数へのアクセス自体はアトミック性が保証されているけど、インクリメントのような複合操作はアトミックにはならない。上記の例では書き込み時はインクリメントしているのでsynchronizedで保護してあげなくちゃいけないけど、読み込み時は問題ない。これがもし、countフィールドにvolatile宣言をしていないと「可視性」が保証されないことになるので、別スレッドが書き込んだ値の最新値を別スレッドが読み込む保証がなくなってしまう。アトミック性(原子性)が保証されないってのは特にlongやdoubleの変数の場合に、変数書き込みが上位バイトのみとか下位バイトのみされている状態が他のスレッドから見えてしまう可能性があるってことだね。可視性が保証されないってのは各スレッドが変数値のコピーをそれぞれ持っていてもいいってことだね。ここまではいいんだけど、Cのvolatileも同じようなもんかと思ってたら、実は違う。Cのvolatileはアトミック性を保証していない。そもそも、Cのvolatileはスレッドなんてものとは無関係に規定されている。Cのvolatileって何のためにあったんだっけ?Javaのところでは説明していなかったけど、volatileにはもう一つ、コンパイラによる最適化の抑止という意味合いがある。以下のコードを見てみよう。0;}これで、SIGINTが発生した場合に無限ループを抜けられる!と思っても実は抜けられなかったりする。今度はvolatileを付けてみよう。今度はプロンプトに戻ってきた。