SimpleDateFormatのスレッドセキュリティの問題と解決策について


詳細
まずSimpleDateFormatにスレッドセキュリティの問題がある理由を簡単に説明します.SimpleDateFormatはDateFormatクラスを継承し、クラスには保護されたタイプのCalendarオブジェクトがあります.SimpleDateFormatのformatメソッドを見てみましょう.
private StringBuffer format(Date date, StringBuffer toAppendTo,
                                FieldDelegate delegate) {
        // Convert input date to time field list
        calendar.setTime(date);

        boolean useDateFormatSymbols = useDateFormatSymbols();

        for (int i = 0; i < compiledPattern.length; ) {
            int tag = compiledPattern[i] >>> 8;
            int count = compiledPattern[i++] & 0xff;
            if (count == 255) {
                count = compiledPattern[i++] << 16;
                count |= compiledPattern[i++];
            }
        ......
}

赤い行のコードを見ると、formatメソッドがスレッドではなく安全である理由がわかると思います.複数のスレッドがSimpleDateFormatインスタンスを共有する場合、Calendarオブジェクトへの変更は相互に影響し、スレッドセキュリティの問題が発生します.
OK、ソリューション:
1、使用するたびにSimpleDateFormatのインスタンスを作成しますが、パフォーマンスは低下します(現在のjdkの優れたパフォーマンスとソフト・ハードウェアのパフォーマンスの向上で、SimpleDateFormatインスタンスの作成がパフォーマンスに与える影響は明らかではありません).
2、ThreadLocalを使用してマルチスレッド共有インスタンスを回避し、コード:
public class ConcurrentDateUtil {

	private static ThreadLocal DateThreadLocal = new ThreadLocal() {
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

	private static ThreadLocal DateTimeThreadLocal = new ThreadLocal() {
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };

    public static Date parseDate(String dateStr) throws ParseException {
        return DateThreadLocal.get().parse(dateStr);
    }

    public static String formatDate(Date date) {
        return DateThreadLocal.get().format(date);
    }

    public static Date parseDateTime(String dateStr) throws ParseException {
        return DateTimeThreadLocal.get().parse(dateStr);
    }

    public static String formatDateTime(Date date) {
        return DateTimeThreadLocal.get().format(date);
    }
	
}

3、synchronizedやサードパーティ製ツールクラスを使用するなど、他の方法があります.前者は性能に大きな影響を及ぼし、後者は本稿の議論の範囲内ではありません.皆さんは自分で研究する時間があります.