メモ synchronizedとvolatile
Javaではメインメモリとワーキングメモリがある。
各スレッドは直接メインメモリの値にアクセスすることはできず、おのおのワーキングメモリを持っており、メインメモリから値をワーキングメモリにコピーし、それに対して、様々な作業をおこなっている。
ワーキングメモリの値をメインメモリに書くタイミングやメインメモリから値を読み込むタイミングは不定である。
synchronizedメソッドはその同期をはかるためのものである。
synchronizedメソッドに入るとき、ワーキングメモリとメインメモリの同期がとられる。
ワーキングメモリの値はメインメモリにすべて書き出され、ワーキングメモリの値はメインメモリから再度コピーする。
出るときは、ワーキングメモリの値をメインメモリへ書き込む。ワーキングメモリの破棄はおこなわない。
また、synchronizedメソッドは一度にひとつのスレッドからしか実行されない。(微妙に違うけどまぁいいや。)
volatileはフィールドのつけるもので、メモリの同期をおこなう。
volatileのついたフィールドの値を参照するときは、毎回メインメモリからワーキングメモリへコピーし、逆に代入したときは、毎回ワーキングメモリの値をメインメモリに反映する。
また、long型,double型はアトミックにおこなわれる保証がないが、volatileをつけることによってアトミックにおこなわれることが保証される。
アトミックにおこなうというのは、例えば、複数のスレッドがどんなタイミングで同じフィールドに代入をおこなおうが、bitがまざってごちゃごちゃになったりしないということである。