クラス | 説明 |
---|---|
AtomicBoolean |
原子的な更新が可能な
boolean 値です。 |
AtomicInteger |
原子的な更新が可能な
int 値です。 |
AtomicIntegerArray |
要素の原子的な更新が可能な
int 配列です。 |
AtomicIntegerFieldUpdater<T> |
指定されたクラスの指定された
volatile int フィールドの原子更新が可能な、リフレクション・ベースのユーティリティです。 |
AtomicLong |
原子的な更新が可能な
long 値です。 |
AtomicLongArray |
要素の原子的な更新が可能な
long 配列です。 |
AtomicLongFieldUpdater<T> |
指定されたクラスの指定された
volatile long フィールドの原子更新が可能な、リフレクション・ベースのユーティリティです。 |
AtomicMarkableReference<V> |
AtomicMarkableReference は、原子的に更新可能なマーク・ビットとともに、オブジェクト参照を管理します。 |
AtomicReference<V> |
原子的な更新が可能なオブジェクト参照です。
|
AtomicReferenceArray<E> |
要素を原子的に更新可能なオブジェクト参照の配列です。
|
AtomicReferenceFieldUpdater<T,V> |
指定されたクラスの指定された
volatile 参照フィールドの原子更新が可能な、リフレクション・ベースのユーティリティです。 |
AtomicStampedReference<V> |
AtomicStampedReference は、原子的に更新可能な整数「スタンプ」とともに、オブジェクト参照を管理します。 |
DoubleAccumulator |
指定された関数を使用して更新される処理中の
double 値を一緒に保持する1つ以上の変数。 |
DoubleAdder |
初期値ゼロの
double の合計を一緒に保持する1つ以上の変数。 |
LongAccumulator |
指定された関数を使用して更新される処理中の
long 値を一緒に保持する1つ以上の変数。 |
LongAdder |
初期値ゼロの
long の合計を一緒に保持する1つ以上の変数。 |
volatile
値、フィールド、および配列要素の概念を、原子的な条件付き更新操作も提供するクラスにまで拡張します。書式は次のとおりです。
boolean compareAndSet(expectedValue, updateValue);
このメソッド(クラスが異なると引数の型も異なる)がexpectedValue
を現在保持している場合、変数をupdateValue
に原子的に設定し、成功するとtrue
を報告します。また、このパッケージ内のクラスには、値を取得したり無条件に設定したりするメソッドや、あとで説明する弱い条件付き原子更新操作weakCompareAndSet
も含まれます。
これらのメソッド仕様に基づく実装により、最新のプロセッサで使用可能な高効率のマシン・レベル原子命令を使用することが可能になります。ただし、一部のプラットフォームでは、これをサポートすることで、なんらかの内部ロックが伴う可能性があります。このため、メソッドで非ブロッキングが厳密に保証されるわけではありません。スレッドは、操作を実行する前に一時的にブロックを実行することがあります。
AtomicBoolean
、AtomicInteger
、AtomicLong
、およびAtomicReference
クラスのインスタンスは、それぞれ対応する型の単一の変数へのアクセスおよび更新を提供します。各クラスは、その型に対応したユーティリティ・メソッドも提供します。たとえば、AtomicLong
およびAtomicInteger
クラスは、原子増分メソッドを提供します。あるアプリケーションが、次のように通し番号を生成するとします。
class Sequencer {
private final AtomicLong sequenceNumber
= new AtomicLong(0);
public long next() {
return sequenceNumber.getAndIncrement();
}
}
getAndIncrement
のような、関数を値に原子的に適用する新しいユーティリティ関数を定義すると簡単です。たとえば、次のような変換がある場合、
long transform(long input)
ユーティリティ・メソッドを次のように記述してください。
long getAndTransform(AtomicLong var) {
long prev, next;
do {
prev = var.get();
next = transform(prev);
} while (!var.compareAndSet(prev, next));
return prev; // return next; for transformAndGet
}
原子アクセスおよび原子更新のメモリー効果は一般に、『Java言語仕様』(17.4 メモリー・モデル)に記載されている揮発性ルールに従います。
get
には、volatile
変数の読取りのメモリー効果があります。
set
には、volatile
変数の書き込み(割り当て)のメモリー効果があります。
lazySet
には、volatile
変数の書き込み(割り当て)のメモリー効果があります。ただし、それ自体では通常の非volatile
書込みで並べ替えの制約を課さない(以前のではなく)以降のメモリー操作による並べ替えを許可する点が異なります。その他の使用コンテキストとして、lazySet
は(ガベージ・コレクションのための) null代入時に、二度とアクセスされることのない参照を適用することがあります。
weakCompareAndSet
は、変数を原子的に読み取り、条件付きで書き込みますが、happens-beforeの順序付けは作成しないため、weakCompareAndSet
のターゲット以外の変数の以前または以降の読取りと書込みに対する保証は提供しません。
compareAndSet
およびその他のすべての読み取りおよび更新操作(getAndIncrement
など)には、volatile
変数の読取りと書込みの両方のメモリー効果があります。
このパッケージには、単一の値を表すクラスに加え、選択した任意のクラス内の選択した任意のvolatile
フィールドに対するcompareAndSet
操作を取得するために使用できるUpdaterクラスが含まれています。AtomicReferenceFieldUpdater
、AtomicIntegerFieldUpdater
、およびAtomicLongFieldUpdater
は、関連付けられたフィールド型へのアクセスを提供するリフレクション・ベースのユーティリティです。これらは主に、同じノードの複数のvolatile
フィールド(ツリー・ノードのリンクなど)が独立して原子更新の対象となる原子データ構造で使用されます。これらのクラスを使用すると、原子更新の使用方法および使用するタイミングに関する柔軟性が高まります。ただし、リフレクション・ベースの設定が扱いにくい、使用しにくい、保証が弱くなるなどの犠牲を払う必要があります。
AtomicIntegerArray
、AtomicLongArray
、およびAtomicReferenceArray
クラスは、原子操作のサポートをこれらの型の配列にまでさらに拡張します。これらのクラスはまた、通常の配列ではサポートされない、その配列要素に対するvolatile
アクセス・セマンティクスを提供している点でも注目されます。
原子クラスは、適用性が制限されているweakCompareAndSet
メソッドもサポートします。プラットフォームによっては、通常の使用では弱いバージョンの方がcompareAndSet
より効率的な場合がありますが、weakCompareAndSet
メソッドのいずれかの特定の呼出しが見かけ上(つまり、明らかな理由なしで) false
を返す可能性がある点で異なります。false
の戻り値は、必要に応じて操作を再試行できることを示しているだけです。これは、変数がexpectedValue
を保持し、この変数の設定を試みるほかのスレッドが存在しない場合に、呼出しを繰返し実行することで最終的な成功が保証されることに基づいています。そのような見かけ上の失敗は、予想される値と現在の値が等しいかどうかとは関係がない、メモリー競合効果が原因の場合があります。また、weakCompareAndSet
は、通常は同期制御に必要な順序付けの保証を提供しません。ただし、このメソッドは、そのような更新がプログラムのその他のhappens-beforeの順序付けに関係ない場合は、カウンタと統計情報を更新する際に便利です。スレッドがweakCompareAndSet
による原子変数への更新が認識されたとき、weakCompareAndSet
の前に発生したほかの変数への更新も認識されるとは限りません。これは、パフォーマンス統計データを更新する場合などは容認できることもありますが、ほとんどはそうではありません。
AtomicMarkableReference
クラスは、単一のboolean値を参照と関連付けます。たとえば、データ構造の内部でこのビットを使用して、参照中のオブジェクトが論理的に削除済みであることを示せます。AtomicStampedReference
クラスは、整数値を参照と関連付けます。これは、一連の更新に対応するバージョン番号を表す場合などに使用できます。
原子クラスは、非ブロック・データ構造および関連する基盤クラスを実装するための基本単位として主に設計されています。通常、compareAndSet
メソッドはロックの代替ではありません。これは、オブジェクトのクリティカルな更新が単一の変数に制限されている場合にのみ適用されます。
原子クラスは、java.lang.Integer
とそれに関連するクラスに対する汎用の代替クラスではありません。これらは、equals
、hashCode
、compareTo
などのメソッドを定義しません。(原子変数では変更が想定されているため、ハッシュテーブル・キーとしては望ましい選択肢ではないため)。また、クラスは目的のアプリケーションで共通して有用な型に対して提供されます。たとえば、byte
を表すための原子クラスは存在しません。これらの使用頻度の少ないケースでは、AtomicInteger
を使用してbyte
値を保持し、必要に応じてキャストできます。また、Float.floatToRawIntBits(float)
およびFloat.intBitsToFloat(int)
変換を使用してfloatを保持したり、Double.doubleToRawLongBits(double)
およびDouble.longBitsToDouble(long)
変換を使用してdoubleを保持したりすることもできます。
バグまたは機能を送信
詳細なAPIリファレンスおよび開発者ドキュメントについては、Java SEのドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright© 1993, 2014, Oracle and/or its affiliates. All rights reserved.