Java™ Platform
Standard Edition 7

パッケージ java.util.concurrent.atomic

単一の変数に対するロックフリーでスレッドセーフなプログラミングをサポートするクラスの小規模なツールキットです。

参照: 説明

パッケージ java.util.concurrent.atomic の説明

単一の変数に対するロックフリーでスレッドセーフなプログラミングをサポートするクラスの小規模なツールキットです。基本的に、このパッケージ内のクラスは volatile 値、フィールド、および配列要素の概念を、原子的な条件付き更新操作も提供するクラスにまで拡張します。書式は次のとおりです。
   boolean compareAndSet(expectedValue, updateValue);
 

このメソッド (クラスが異なると引数の型も異なる) が expectedValue を現在保持している場合、変数を updateValue に原子的に設定し、成功すると true を報告します。また、このパッケージ内のクラスには、値を取得したり無条件に設定したりするメソッドや、あとで説明する弱い条件付き原子更新操作 weakCompareAndSet も含まれます。

これらのメソッド仕様に基づく実装により、最新のプロセッサで使用可能な高効率のマシンレベル原子命令を使用することが可能になります。ただし、一部のプラットフォームでは、これをサポートすることで、なんらかの内部ロックが伴う可能性があります。このため、メソッドで非ブロッキングが厳密に保証されるわけではありません。スレッドは、操作を実行する前に一時的にブロックを実行することがあります。

AtomicBooleanAtomicIntegerAtomicLong、および AtomicReference クラスのインスタンスは、それぞれ対応する型の単一の変数へのアクセスおよび更新を提供します。各クラスは、その型に対応したユーティリティーメソッドも提供します。たとえば、AtomicLong および AtomicInteger クラスは、原子増分メソッドを提供します。あるアプリケーションが、次のように通し番号を生成するとします。

 class Sequencer {
   private final AtomicLong sequenceNumber
     = new AtomicLong(0);
   public long next() {
     return sequenceNumber.getAndIncrement();
   }
 }
 

原子アクセスおよび原子更新のメモリー効果は一般に、『Java™ 言語仕様』のセクション 17.4 に記載されている揮発性規則に従います。

このパッケージには、単一の値を表すクラスに加え、選択した任意のクラス内の選択された任意の volatile フィールドに対する compareAndSet 操作を取得するために使用できる Updater クラスが含まれています。 AtomicReferenceFieldUpdaterAtomicIntegerFieldUpdater、および AtomicLongFieldUpdater は、関連付けられたフィールド型へのアクセスを提供するリフレクションベースのユーティリティーです。これらは主に、同じノードの複数の volatile フィールド (ツリーノードのリンクなど) が独立して原子更新の対象となる原子データ構造で使用されます。これらのクラスを使用すると、原子更新の使用方法および使用するタイミングに関する柔軟性が高まります。ただし、リフレクションベースの設定が扱いにくい、使用しにくい、保証が弱くなるなどの犠牲を払う必要があります。

AtomicIntegerArrayAtomicLongArray、および AtomicReferenceArray クラスは、原子操作のサポートをこれらの型の配列にまでさらに拡張します。これらのクラスはまた、通常の配列ではサポートされない、その配列要素に対する volatile アクセスセマンティクスを提供している点でも注目されます。

原子クラスは、適用性が制限されている weakCompareAndSet メソッドもサポートします。プラットフォームによっては、通常の使用では弱いバージョンの方が compareAndSet より効率的な場合がありますが、weakCompareAndSet メソッドのいずれかの特定の呼び出しが見かけ上 (つまり、明らかな理由なしで) false を返す可能性がある点で異なります。false の戻り値は、必要に応じて操作を再試行できることを示しているだけです。これは、変数が expectedValue を保持し、この変数の設定を試みるほかのスレッドが存在しない場合に、呼び出しを繰り返し実行することで最終的な成功が保証されることに基づいています。そのような見かけ上の失敗は、予想される値と現在の値が等しいかどうかとは関係がない、メモリー競合効果が原因の場合があります。また、weakCompareAndSet は、通常は同期制御に必要な順序付けの保証を提供しません。ただし、このメソッドは、そのような更新がプログラムのその他の happens-before の順序付けに関係ない場合は、カウンタと統計情報を更新する際に便利です。スレッドが weakCompareAndSet による原子変数への更新が認識されたとき、weakCompareAndSet の前に発生したほかの変数への更新も認識されるとは限りません。これは、パフォーマンス統計データを更新する場合などは容認できることもありますが、ほとんどはそうではありません。

AtomicMarkableReference クラスは、単一の boolean 値を参照と関連付けます。たとえば、データ構造の内部でこのビットを使用して、参照中のオブジェクトが論理的に削除済みであることを示せます。 AtomicStampedReference クラスは、整数値を参照と関連付けます。これは、一連の更新に対応するバージョン番号を表す場合などに使用できます。

原子クラスは、非ブロックデータ構造および関連する基盤クラスを実装するための基本単位として主に設計されています。通常、compareAndSet メソッドはロックの代替ではありません。これは、オブジェクトのクリティカルな更新が単一の変数に制限されている場合にのみ適用されます。

原子クラスは、java.lang.Integer とそれに関連するクラスに対する汎用の代替クラスではありません。これらは、hashCodecompareTo などのメソッドを定義しません。(原子変数では変更が想定されているため、ハッシュテーブルキーとしては望ましい選択肢ではないため)。また、クラスは目的のアプリケーションで共通して有用な型に対して提供されます。たとえば、byte を表すための原子クラスは存在しません。これらの使用頻度の少ないケースでは、AtomicInteger を使用して byte 値を保持し、必要に応じてキャストできます。 また、Float.floatToIntBits(float) および Float.intBitsToFloat(int) 変換を使用して float を保持したり、Double.doubleToLongBits(double) および Double.longBitsToDouble(long) 変換を使用して double を保持したりすることもできます。

導入されたバージョン:
1.5
Java™ Platform
Standard Edition 7

バグまたは機能を送信
詳細な API リファレンスおよび開発者ドキュメントについては、Java SE のドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.