[Java] SimpleDateFormatの罠

SimpleDateFormatはスレッドセーフではない。スレッド1でformatに引数を与えて戻り値が帰ってくるまでの間に、スレッド2のformatの処理が割り込むと、スレッド1の戻り値がスレッド2の引数によるものになる。同じSimpleDateFormatのインスタンスを短時間で大量に使い回す場合は要注意。
synchronizedを使うことで解決できる。

public class SimpleDateFormatTest {
    private static SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");

    public static void main(String[] args) {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                System.out.println("thread1: " + format(new Date()));
            }
        };

        Thread t2 = new Thread() {
            @Override
            public void run() {
                System.out.println("thread2: " + format(new Date(new Date().getTime() - 24*60*60*1000)));
            }
        };

        t1.start();
        t2.start();
    }

    synchronized private static String format(Date date) { //このsynchronizedがなければ予期しない動作となる
        return format.format(date);
    }
}