序文
マルチスレッド状況で日付変換に SimpleDateFormat を使用すると、java.lang.NumberFormatException 問題が発生します。
1.日付変換用のSimpleDateFormat
コードは以下のように表示されます。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
for(int i = 0; i < 10; i++){
new Thread(() -> {
try {
log.debug("{}",sdf.parse("1995-09-04"));//log是使用了@Self4j注解
}catch (Exception e){
log.error("{}",e);
}
}).start();
}
SimpleDateFormat はスレッドセーフではないため、このコードには java.lang.NumberFormatException の問題が発生するか、不正な日付解析結果が発生する可能性があります。
2. 解決策 1: Java8 によって提供される DateTimeFormatter
コードは以下のように表示されます。
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
for(int i = 0; i < 10; i++){
new Thread(() -> {
LocalDate date = dtf.parse("1995-09-04",LocalDate::form);
log.debug("{}",date);
}).start();
}
このクラスは不変でスレッドセーフであることがわかります。
3. 解決策 2
コードは以下のように表示されます。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
for(int i = 0; i < 10; i++){
new Thread(() -> {
synchronize (sdf){
try {
log.debug("{}",sdf.parse("1995-09-04"));//log是使用了@Self4j注解
}catch (Exception e){
log.error("{}",e);
}
}
}).start();
}
これにより問題は解決しますが、パフォーマンスが低下するため、使用はお勧めできません。方法 1 を使用することをお勧めします。