SimpleDateFormat线程不安全问题解决及替换方法

    场景:在多线程情况下为避免多次创建SimpleDateForma实力占用资源,将SimpleDateForma对象设置为static。

 出现错误:SimpleDateFormat定义为静态变量,那么多线程下SimpleDateFormat的实例就会被多个线程共享,B线程会读取到A线程的时间,就会出现时间差异和其它各种问题。SimpleDateFormat和它继承的DateFormat类也不是线程安全的。

 错误原因:SimpleDateFormat的format()方法的源码,实际操作的是 calendar.setTime(date)。

 假设线程A执行完calendar.setTime(date),把时间设置成2019-01-02,这时候被挂起,线程B获得CPU执行权。线程B也执行到了calendar.setTime(date),把时间设置为2019-01-03。线程挂起,线程A继续走,calendar还会被继续使用(subFormat方法),而这时calendar用的是线程B设置的值了,而这就是引发问题的根源,出现时间不对,线程挂死等等。

 解决方案:

   1 ThreadLocal可以确保每个线程都可以得到单独的一个SimpleDateFormat的对象

   
private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() {   return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } }; public static Date parse(String dateStr) throws ParseException { return threadLocal.get().parse(dateStr); } public static String format(Date date) {   return threadLocal.get().format(date); }

  2 基于JDK1.8的DateTimeFormatter

  

public static String formatDate2(LocalDateTime date) {        
 return formatter.format(date); } public static LocalDateTime parse2(String dateNow) { return LocalDateTime.parse(dateNow, formatter); }

参考原文:http://blog.itpub.net/69900354/viewspace-2629912/

点赞