常にAtomicIntegerをデータメンバーとして使用しない理由はありますか?
はい、常に使用するとは限らないのには十分な理由がありますAtomicInteger
。 基になる値 を設定/取得するために使用されているローカルおよび他の構成よりも構成がAtomicInteger
原因で、少なくとも1桁遅くなる可能性があります(おそらくそれ以上) 。これは、アクセスするたびにメモリバリアを越えることを意味します。これにより、問題のプロセッサでキャッシュメモリがフラッシュされます。volatile
int
Unsafe
int
volatile
AtomicInteger
また、すべてのフィールドを作成したからといってAtomicInteger
、複数のフィールドにアクセスしているときの競合状態から保護することはできません。volatile
、、synchronized
およびAtomic*
クラスをいつ使用するかについて適切な決定を下す以外に方法はありません。
たとえば、スレッドプログラムで信頼できる方法でアクセスしたいクラスに2つのフィールドがある場合、次のようにします。
synchronized (someObject) {
someObject.count++;
someObject.total += someObject.count;
}
これらのメンバーの両方が2回AtomicInteger
アクセスする場合はvolatile
、1つではなく2つのメモリバリアを通過します。また、割り当ては、Unsafe
内の操作よりも高速ですAtomicInteger
。また、(上記のブロックとは対照的に)2つの操作でのデータの競合状態のsynchronized
ため、の正しい値が得られない場合がありますtotal
。
スレッドセーフなintデータメンバーの使用例を教えてください。
それを作成することを除いて、それをマークするか、を使用することを除いfinal
て、スレッドセーフなデータメンバーのためのメカニズムはありません。すべてのフィールドでスレッドセーフをペイントする魔法の方法はありません。もしあれば、スレッドプログラミングは簡単でしょう。課題は、ブロックを配置する適切な場所を見つけることです。でマークする必要がある適切なフィールドを見つけるため。使用する適切な場所と友達を見つけるため。int
volatile
AtomicInteger
synchronized
volatile
AtomicInteger