AtomicBooleanの使用方法とそのクラスの目的は何ですか?
複数のスレッドがブール値を確認および変更する必要がある場合。例えば:
if (!initialized) {
initialize();
initialized = true;
}
これはスレッドセーフではありません。 AtomicBoolean
を使用して修正できます。
if (atomicInitialized.compareAndSet(false, true)) {
initialize();
}
ここにメモがあります( Brian Goetz book から)私が作った、それはあなたの助けになるかもしれません
AtomicXXXクラス
ノンブロッキングCompare-And-Swap実装を提供する
ハードウェア(IntelのCMPXCHG命令)が提供するサポートを利用します。これらのアトミックな同時実行APIを使用するコードで多くのスレッドが実行されている場合、オブジェクトレベルのモニター/同期を使用するコードよりもはるかに優れたスケーラビリティを発揮します。 Javaの同期メカニズムはコードを待機させるため、クリティカルセクションを通過するスレッドが多数ある場合、同期メカニズム自体の管理(待機、通知など)にかなりのCPU時間を費やします。新しいAPIは、ハードウェアレベルの構造(原子変数)と待機およびロックフリーアルゴリズムを使用してスレッドセーフを実装するため、同期の管理ではなく「処理」に多くのCPU時間を費やします。
スループットが向上するだけでなく、デッドロックや優先順位の逆転などの活性の問題に対する耐性も向上します。
アトミックブール値を使用できる主な理由は2つあります。最初に変更可能です。たとえば、参照として渡し、ブール値自体に関連付けられている値を変更できます。
public final class MyThreadSafeClass{
private AtomicBoolean myBoolean = new AtomicBoolean(false);
private SomeThreadSafeObject someObject = new SomeThreadSafeObject();
public boolean doSomething(){
someObject.doSomeWork(myBoolean);
return myBoolean.get(); //will return true
}
}
およびsomeObjectクラス
public final class SomeThreadSafeObject{
public void doSomeWork(AtomicBoolean b){
b.set(true);
}
}
さらに重要なことは、そのスレッドセーフであり、クラスを維持している開発者に、この変数が変更され、複数のスレッドから読み取られることを示すことができることです。 AtomicBooleanを使用しない場合は、揮発性を宣言するか、フィールドの読み取りと書き込みを中心に同期することにより、使用しているブール変数を同期する必要があります。
AtomicBoolean
クラスは、アトミックに更新できるブール値を提供します。ブール変数にアクセスする複数のスレッドがある場合に使用します。
Java.util.concurrent.atomicパッケージの概要 を使用すると、このパッケージのクラスが何をするのか、いつ使用するのかについての高レベルな説明を得ることができます。また、Brian Goetzの著書 実践におけるJava並行性 もお勧めします。
パッケージの説明 からの抜粋
パッケージJava.util.concurrent.atomicの説明:単一変数のロックフリースレッドセーフプログラミングをサポートするクラスの小さなツールキット。[...]
これらのメソッドの仕様により、実装は、最新のプロセッサで利用可能な効率的なマシンレベルのアトミック命令を使用できます。[...]
クラスAtomicBoolean、AtomicInteger、AtomicLong、およびAtomicReferenceのインスタンスはそれぞれ、対応する型の単一変数へのアクセスと更新を提供します。[...]
アトミックのアクセスと更新のメモリ効果は、通常、volatilesのルールに従います:
- getには、揮発性変数を読み取るメモリ効果があります。
- setには、揮発性変数の書き込み(割り当て)のメモリ効果があります。
- weakCompareAndSetは変数をアトミックに読み取り、条件付きで書き込み、その変数に対する他のメモリ操作に関して順序付けられますが、それ以外は通常の不揮発性メモリ操作として機能します。
- compareAndSetおよびgetAndIncrementなどの他のすべての読み取りおよび更新操作には、揮発性変数の読み取りと書き込みの両方のメモリ効果があります。