要注意! Javaの SimpleDateFormat はスレットセーフではない

2021年7月19日月曜日

Java

t f B! P L

SimpleDateFormat はスレッドセーフではない…

知っている人にとっては当たり前のことかもしれないが、知らないとハッキリ言って開発工程で問題に気づくことは不可能に近い。

まぁ、 JavaDoc に思いっきりスレッドセーフではないと書かれているが…

同期
日付フォーマットは同期化されません。スレッドごとに別のフォーマット・インスタンスを作成することをお薦めします。複数のスレッドがフォーマットに並行してアクセスする場合は、外部的に同期化する必要があります。
https://docs.oracle.com/javase/jp/8/docs/api/java/text/SimpleDateFormat.html

スポンサーリンク

並列処理で SimpleDateFormat を使うとヤバい

例えば、なんの変哲もない、現在時刻を yyyy/MM/dd HH:mm:ss で書式化するコードでも、並列処理で SimpleDateFormat のインスタンスを共有し、それを同時に使用すると、ヤバい結果になることがある。

//現在時刻のインスタンスを取得
Calendar cal = Calendar.getInstance();

//SimpleDateFormatで書式を指定
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
System.out.println(sdf.format(cal.getTime()));

こんな感じになった.... なんか時間が変だ....
2021/07/19 0012:12:00

とにかくDateTimeFormatter を使え

解決策は簡単だ。

SimpleDateFormat のインスタンスを生成するか、次のサンプルコードに示すような DateTimeFormatterを使えば良い!!

// DateTimeFormatterを取得
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");

// システム日付を、DateTimeFormatterで指定したフォーマットで文字列に変換
String str = LocalDateTime.now().format(dtf);
System.out.println(str);
スポンサーリンク

QooQ