前言
在多线程情况下使用SimpleDateFormat进行日期转换时出现java.lang.NumberFormatException问题。
一、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();
}
这段代码很可能出现java.lang.NumberFormatException问题或者出现不正确的日期解析结果,因为SimpleDateFormat不是线程安全的。
二、解决方法一: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();
}
可以看到这个类是不可变的而且是线程安全的。
三、解决方法二
代码如下:
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();
}
这样虽然能解决问题,但是带来性能上的损失,所以不建议使用,比较建议使用方法一。