Javaの並行性-AtomicIntegerクラス
java.util.concurrent.atomic.AtomicIntegerクラスは、アトミックに読み書きできる基礎となるint値に対する操作を提供し、高度なアトミック操作も含みます。AtomicIntegerは、基になるint変数に対するアトミック操作をサポートします。揮発性変数の読み取りと書き込みのように機能するgetメソッドとsetメソッドがあります。つまり、セットには、同じ変数に対する後続のgetとの発生前の関係があります。アトミックcompareAndSetメソッドには、これらのメモリ整合性機能もあります。
AtomicIntegerメソッド
以下は、AtomicIntegerクラスで使用可能な重要なメソッドのリストです。
シニア番号 | 方法と説明 |
---|---|
1 | public int addAndGet(int delta) 指定された値を現在の値に原子的に追加します。 |
2 | public boolean compareAndSet(int expect, int update) 現在の値が期待値と同じである場合、原子的に値を指定された更新値に設定します。 |
3 | public int decrementAndGet() 原子的に現在の値を1つ減らします。 |
4 | public double doubleValue() 指定された数値の値をdoubleとして返します。 |
5 | public float floatValue() 指定された数値の値をfloatとして返します。 |
6 | public int get() 現在の値を取得します。 |
7 | public int getAndAdd(int delta) 指定された値を現在の値にアトミックに追加します。 |
8 | public int getAndDecrement() 原子的に現在の値を1つ減らします。 |
9 | public int getAndIncrement() 現在の値を1つ原子的にインクリメントします。 |
10 | public int getAndSet(int newValue) 原子的に指定された値に設定され、古い値を返します。 |
11 | public int incrementAndGet() 現在の値を1つ原子的にインクリメントします。 |
12 | public int intValue() 指定された数値の値をintとして返します。 |
13 | public void lazySet(int newValue) 最終的には指定された値に設定されます。 |
14 | public long longValue() 指定された数値の値をlongとして返します。 |
15 | public void set(int newValue) 指定された値に設定します。 |
16 | public String toString() 現在の値の文字列表現を返します。 |
17 | public boolean weakCompareAndSet(int expect, int update) 現在の値が期待値と同じである場合、原子的に値を指定された更新値に設定します。 |
例
次のTestThreadプログラムは、スレッドベースの環境でのカウンターの安全でない実装を示しています。
public class TestThread {
static class Counter {
private int c = 0;
public void increment() {
c++;
}
public int value() {
return c;
}
}
public static void main(final String[] arguments) throws InterruptedException {
final Counter counter = new Counter();
//1000 threads
for(int i = 0; i < 1000 ; i++) {
new Thread(new Runnable() {
public void run() {
counter.increment();
}
}).start();
}
Thread.sleep(6000);
System.out.println("Final number (should be 1000): " + counter.value());
}
}
これにより、コンピューターの速度とスレッドのインターリーブによっては、次の結果が生じる場合があります。
出力
Final number (should be 1000): 1000
例
次のTestThreadプログラムは、スレッドベースの環境でAtomicIntegerを使用したカウンターの安全な実装を示しています。import java.util.concurrent.atomic.AtomicInteger;
public class TestThread {
static class Counter {
private AtomicInteger c = new AtomicInteger(0);
public void increment() {
c.getAndIncrement();
}
public int value() {
return c.get();
}
}
public static void main(final String[] arguments) throws InterruptedException {
final Counter counter = new Counter();
//1000 threads
for(int i = 0; i < 1000 ; i++) {
new Thread(new Runnable() {
public void run() {
counter.increment();
}
}).start();
}
Thread.sleep(6000);
System.out.println("Final number (should be 1000): " + counter.value());
}
}
これにより、次の結果が得られます。
出力
Final number (should be 1000): 1000