AtomicXxxxxクラス
ロックフリーな同期処理を実装する – AtomicXxxxxクラスjava.util.concurrent.atomicパッケージでは、値の代入/取得といった処理をハードウェアレベルでアトミックに実行する手段を提供します。
・AtomicBoolean
・AtomicInteger
・AtomicIntegerArray
・AtomicLong
・AtomicLongArray
これらのクラスを利用することで、synchronized修飾子、ReentrantLockクラスのようにロックを取得することなく、処理を同期させることが可能になります。
それぞれのクラスで利用できる処理には、以下のようなものがあります。
| AtomicXxxxxクラスの主なメソッド(*はAtomicBooleanでは利用できないもの) | |
|---|---|
| メソッド | 概要 |
| get() | 現在の値を取得 |
| getAndSet(newValue) | 現在の値を取得し、指定された値を設定 |
| set(newValue) | 指定された値を設定 |
| *getAndAdd(delta) | 指定された値を追加(操作前の値を取得) |
| *addAndGet(delta) | 指定された値を追加(操作後の値を取得) |
| *getAndDecrement() | 現在の値を1デクリメント(操作前の値を取得) |
| *decrementAndGet() | 現在の値を1デクリメント(操作後の値を取得) |
| *getAndIncrement() | 現在の値を1インクリメント(操作前の値を取得) |
| *incrementAndGet() | 現在の値を1インクリメント(操作後の値を取得) |
以下は、synchronized修飾子の項のサンプル(incrementメソッド)をAtomicIntegerクラスで書き換えたものです。標準的な「i++」演算はアトミックではありませんが、AtomicInteger#getAndIncrementメソッドはアトミックなので、値の取得からインクリメント、再代入の過程に他のスレッドが割り込むことはありません。
AtomicSample.java
package com.example.mynavi.thread;
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicSample {
private AtomicInteger count = new AtomicInteger();
public static void main(String[] args) {
AtomicSample as = new AtomicSample();
as.execute();
}
public void execute() {
final int THREAD_MAX = 300000;
Thread[] ts = new Thread[THREAD_MAX];
for (int i = 0; i < THREAD_MAX; i++) {
ts[i] = new Thread(new MyThread(this));
ts[i].start();
}
for (int i = 0; i < THREAD_MAX; i++) {
try {
ts[i].join();
} catch (InterruptedException e) {
System.out.println(e);
}
}
System.out.println(count);
}
public void increment() {
count.getAndIncrement();
}
private static class MyThread implements Runnable {
private AtomicSample _counter;
public MyThread(AtomicSample counter) {
this._counter = counter;
}
@Override
public void run() {
_counter.increment();
}
}
}






