AtomicReferenceはVクラス(Generic)のオブジェクトをwrappingクラスです。 AtomicReferenceクラスは、マルチスレッド環境での同時実行を保証します。
Javaで同時実行の問題を解決するための3つの方法があります。
- "volatile"は、Thread1で書き、Thread2で読み取る場合のみ同時実行を保証します。二つのスレッドで書いた場合、問題になることがあります
- "synchronized"を使えば、安全に同時実行を保証することができます。しかし、コストが最も大きい
- Atomicクラスは、(CAS compare-and-swap)を利用して、同時実行を保証します。複数のスレッドからのデータをwriteしても問題はありません
AtomicReferenceはsynchronizedよりも少ないコストで同時実行を保証することができます。
AtomicReferenceを使用する方法について説明します。
オブジェクトの作成
AtomicReferenceはGeneric classで実装されて、様々なクラスと一緒に使用することができます。
Integerオブジェクトを持つ AtomicReference<Integer>
を例に作成してみましょう。
コンストラクタの初期値を渡すことができ、入力しない場合、オブジェクトはnullに初期化されます。
public void atomicReference1() {
AtomicReference<Integer> atomic = new AtomicReference<>();
System.out.println("atomic : " + atomic.get());
AtomicReference<Integer> atomic2 = new AtomicReference<>(10);
System.out.println("atomic2 : " + atomic2.get());
}
結果
atomic : null
atomic2 : 10
get(), set(), getAndSet()
AtomicReferenceの値を set(V newValue)
メソッドを、値を読むには get()
メソッドを使用します。
public void atomicReference2() {
AtomicReference<Integer> atomic = new AtomicReference<>();
System.out.println("value : " + atomic.get());
atomic.set(100);
System.out.println("value : " + atomic.get());
}
結果
value : null
value : 100
getAndSet(V newValue)
は、現在のvalueを返し、引数として渡された値に更新します。
public void atomicReference3() {
AtomicReference<Integer> atomic = new AtomicReference<>(10);
System.out.println("value(before setting) : " + atomic.getAndSet(20));
System.out.println("value(after setting) : " + atomic.get());
}
結果
value(before setting) : 10
value(after setting) : 20
compareAndSet()
compareAndSet(expect、update)は、現在の値が予想される値(expect)と同じであればupdate値に変更してくれて、trueを返してくれます。 そうでない場合、データの変更はなくfalseを返します。
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(V expect, V update)
以下は、compareAndSet()を使用している例です。現在の値と一致する場合にのみ、データが更新され、trueが返されます。
public void atomicReference4() {
int expected = 20;
AtomicReference<Integer> atomic = new AtomicReference<>(10);
System.out.println("success ? " + atomic.compareAndSet(expected, 100));
System.out.println("value : " + atomic.get());
atomic.set(20);
System.out.println("success ? " + atomic.compareAndSet(expected, 100));
System.out.println("value : " + atomic.get());
}
結果
success ? false
value : 10
success ? true
value : 100
参考
Related Posts
- Java - AtomicReference使用方法
- Java - CountDownLatchを使用する方法、および例
- Java - ScheduledThreadPoolExecutor使用方法
- Java - SummaryStatisticsの使用方法(count、min、max、average)
- Java8 - 関数型インタフェース (Functional Interface) について
- Java - String配列をint配列に変換する
- Java - ArrayList要素の値を変更する方法、replaceAll()
- Java - 2つのリストが同じかどうかを比較
- Java - 配列から特定のIndex要素を削除する3つの方法
- Java - HashMapソート、4つの方法
- Java - 文字列を配列に変換する方法
- Java - ArrayListが空であることを確認する3つの方法
- Java - ArrayListの巡回、4つの方法
- Java - ArrayListの最大値、最小 値を見つける
- Java - ArrayListの合計、平均値の計算
- Java - HashMap巡回、3つの方法
- Java - do whileとwhileの違い
- Java - Lambda式と関数型インタフェース
- Java - List empty(null)チェック、3つの方法
- Java - ArrayListの初期化、4つの方法
- Java - Stream.reduce()の使い方と例
- Java - 2つのマップを結合する(merge、putAll)
- Java - java.util.Dateをjava.sql.Dateに変換する
- Java - ArrayListをStringに変換する
- Java - ClassNotFoundExceptionの発生原因と解決策
- Java - 非静的メソッドは静的コンテキストから参照できません
- Java - NoSuchMethodErrorの原因と解決策
- Java - JSONライブラリを使用する方法(JSONObject、JSONArray)
- Java - byte[]配列をFileに保存
- Java - byte[]の配列をStringに変換
- Java - ファイルのアクセス権を確認し、変更
- Java - 一時フォルダ(Temp directory)パスを取得する
- Javaでシェルスクリプトを実行
- Java - Streamを配列に変換する
- Java - リスト重複排除、2つの方法