Effective Java の本には次のように書かれています。
long
言語仕様では、変数が型またはdouble
[JLS、17.4.7]でない限り、変数の読み取りまたは書き込みはアトミックであることが保証されています。
Java プログラミング、または一般的なプログラミングの文脈において、「アトミック」とはどういう意味ですか?
ベストアンサー1
次に例を示します。 がfoo
型の変数であるとするとlong
、次の操作はアトミック操作ではありません ( Java の場合)。
foo = 65465498L;
実際、変数は 2 つの別々の操作を使用して書き込まれます。1 つは最初の 32 ビットを書き込む操作で、もう 1 つは最後の 32 ビットを書き込む操作です。つまり、別のスレッドが の値を読み取りfoo
、中間状態を確認する可能性があります。
操作をアトミックにするには、同期メカニズムを使用して、他のスレッドから操作が単一のアトミック (つまり、分割できない) 操作として認識されるようにします。つまり、操作がアトミックになると、他のスレッドはfoo
割り当て前の値または割り当て後の値を参照することになります。ただし、中間値は参照できません。
これを実現する簡単な方法は、可変の揮発性:
private volatile long foo;
または、変数へのすべてのアクセスを同期するには、次のようにします。
public synchronized void setFoo(long value) {
this.foo = value;
}
public synchronized long getFoo() {
return this.foo;
}
// no other use of foo outside of these two methods, unless also synchronized
または、AtomicLong
:
private AtomicLong foo;