Skip to content
閲覧中:
Automatic変数

iJavaのAtomic変数についての解説をMarkdown形式でまとめました。

このままファイル(例:java_atomic.md)として保存し、VS Codeのプレビュー機能や pandoc などを使ってPDFに変換してご活用ください。


Java Atomic変数 解説資料

1. Atomic変数とは?

Javaの java.util.concurrent.atomic パッケージに含まれるクラス群です。 マルチスレッド環境において、**ロック(synchronized)を使わずに、変数への操作を「不可分(Atomic)」に行う**ために使用されます。

なぜ必要なのか?

通常の int 型に対する count++ は、内部で「読み込み」「加算」「書き込み」の3つのステップに分かれています。複数のスレッドが同時にこれを行うと、計算結果が上書きされて消えてしまう**データ競合(Race Condition)**が発生します。


2. 核心技術:CAS (Compare-And-Swap)

Atomicクラスは、CPUレベルの命令である CAS を利用してスレッドセーフを実現しています。

  1. 比較: 現在の変数の値が、自分の知っている値(期待値)と同じか確認する。
  2. 置換: 同じであれば、新しい値に書き換える。
  3. リトライ: もし他者が先に書き換えていて値が違っていたら、失敗として値を読み直してやり直す。

この仕組みにより、スレッドを停止(ブロック)させることなく安全な更新が可能です。


3. 主要なクラスとメソッド

クラス 説明
AtomicInteger int型の値を操作
AtomicBoolean boolean型の値を操作
AtomicReference<V> オブジェクトの参照を操作

よく使われるメソッド (AtomicIntegerの例)

  • get() : 現在の値を返す。
  • set(int newValue) : 値を更新する。
  • incrementAndGet() : 1増やした後の値を返す (++i)。
  • getAndIncrement() : 増やす前の値を返す (i++)。
  • compareAndSet(int expect, int update) : 値が expect なら update に更新し、成否を boolean で返す。

4. 演習問題

以下の知識を確認するための問題です。

第1問:基本概念

マルチスレッド環境において、以下のコードを10個のスレッドで同時に1000回ずつ実行しました。実行後の count の値が必ずしも 10000 にならない理由を説明してください。

Java
int count = 0;
void increment() {
    count++;
}

第2問:メソッドの選択

AtomicInteger を使って、「現在の値が 10 の場合のみ、値を 20 に更新する」 という処理を実装したい場合、どのメソッドを使用するのが適切ですか?また、そのメソッドの戻り値は何を表しますか?

第3問:実行結果の予測

以下のプログラムを実行した際、コンソールに出力される値は何ですか?

Java
AtomicInteger atomic = new AtomicInteger(5);
int result = atomic.addAndGet(10);
System.out.println(result);
System.out.println(atomic.get());

5. 解答

第1問

count++ 操作が 原子(Atomic)的ではないから です。 「値の読み込み」「加算」「書き込み」の間に他のスレッドが割り込んで古い値を読み込んでしまうため、更新の衝突(ロストアップデート)が発生します。

第2問

  • メソッド: compareAndSet(10, 20)
  • 戻り値: 更新に成功した場合は true、現在の値が期待値(10)と異なり更新できなかった場合は false を返します。

第3問

  • 1つ目の出力: 15 (addAndGet は加算後の値を返すため)
  • 2つ目の出力: 15 (変数自体の値も更新されているため)

このMarkdownをPDF化するお手伝いや、さらに詳細なコード例が必要であれば教えてくださいね。ビルドしたEmacsでこのMarkdownを編集するのも良い練習になるかもしれません!