マルチスレッド対応カウンタ

Javaの++演算子はアトミックじゃない。つまり、++nは、n = n + 1と分解されたとき、nを読み込んだ後、1足した値をnに書き込む前に他のスレッドがnを変更していたら、すでに他のスレッドで行っていた変更が無効になる。
で、これはvolatileをつけてもだめ。
つまり、このプログラムの実行結果が20000にならない。

public class NonAtomicIncrement {
    static int count;
    public static void main(String[] args) throws InterruptedException{
        Thread t = new Thread(){
            @Override public void run(){
                for(int i = 0; i < 10000; ++i){
                    ++count;
                }
            }
        };
        t.start();
        for(int i = 0; i < 10000; ++i){
            ++count;
        }
        t.join();
        System.out.println(count);
    }
}

なので、synchronizedを使う必要があったのだけど、Java2SE 5.0からはAtomicIntegerなるものが用意されているので、これを使うと便利

import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIncrement {
    static AtomicInteger count = new AtomicInteger();
    public static void main(String[] args) throws InterruptedException{
        Thread t = new Thread(){
            @Override public void run(){
                for(int i = 0; i < 10000; ++i){
                    count.incrementAndGet();
                }
            }
        };
        t.start();
        for(int i = 0; i < 10000; ++i){
            count.incrementAndGet();
        }
        t.join();
        System.out.println(count);
    }
}