SimpleDateFormat執行緒不安全導致的問題
阿新 • • 發佈:2018-12-10
執行緒安全日期格式化操作的幾種方式
由於 DateFormat
是非執行緒安全的,因此在多執行緒併發情況下日期格式化時需要特別注意。下面記錄幾種格式化的方式:
執行緒不安全的處理方式
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//執行緒不安全
這種方式會報如下異常:
java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java: 65)
at java.lang.Long.parseLong(Long.java:601)
at java.lang.Long.parseLong(Long.java:631)
at java.text.DigitList.getLong(DigitList.java:195)
at java.text.DecimalFormat.parse(DecimalFormat.java:2051)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2162)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java: 1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at com.concurrent.DateUtils.parse(DateUtils.java:28)
at com.concurrent.DateUtils$2.run(DateUtils.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java: 617)
at java.lang.Thread.run(Thread.java:745)
執行緒安全的處理方式
方式一,每次new一個物件
public static Date parse(String date) throws ParseException {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date);
}
方式二,通過ThreadLocal進行處理
private static final ThreadLocal<DateFormat> LOCAL_DATE_FORMAT = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
- 如果是JDK7及以下的應用,可用ThreadLocal的方式
方式三,java8 通過 DateTimeFormatter 進行處理
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(date, DATE_TIME_FORMATTER);
LOCAL_DATE_FORMAT.get().parse(date);
- 如果是JDK8的應用,可以使用instant代替Date,Localdatetime代替Calendar,Datetimeformatter代替Simpledateformatter,官方給出的解釋:simple beautiful strong immutable thread-safe。