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

JAVA学习网 2019-07-09 16:33:01

    场景:在多线程情况下为避免多次创建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/

阅读(2534) 评论(0)