SimpleDateFormat 时间转换异常

Java爬坑 之 SimpleDateFormat 时间转换异常

前言

SimpleDateFormat 一个今本上天天在用的 Java类,但是使用不当会出现莫名的错误,如:抛异常、转换结果错误等;
因为 SimpleDateFormat 和 DateFormat 类都是线程不安全的,所以不能使用工具类直接创建静态实例,平常开发环境 并发较少体现不出问题,一旦上正式出现多线程、高并发、负载的情况下就会出现

解决办法

每次使用创建新实例

每次创建新实例会将对象变为局部变量从而解决问题,但是也会创建很多对象,但是一般来说可以忽略

public class DateUtil {
    
    public static  String formatDate(Date date)throws ParseException{
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }
    
    public static Date parse(String strDate) throws ParseException{
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.parse(strDate);
    }
}

使用同步锁 synchronized

多线程调用会出现线程等待 阻塞 ,会对高并发造成一定的影响

public class DateUtil {

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      
    public static String formatDate(Date date)throws ParseException{
        synchronized(sdf){
            return sdf.format(date);
        }  
    }
    
    public static Date parse(String strDate) throws ParseException{
        synchronized(sdf){
            return sdf.parse(strDate);
        }
    } 
}

使用ThreadLocal

ThreadLocal 是线程的局部变量,是每一个线程所单独持有的,其他线程不能对其进行访问,由于在每个线程中都创建了副本,所以要考虑它对资源的消耗

  1. 重写 initialValue 方法
public class DateUtil {

    private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
        
        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);
    }
}
  1. 调用 set() 方法赋值
public class DateUtil {

    private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(); 
 
    public static DateFormat getDateFormat()   
    {  
        DateFormat df = threadLocal.get();  
        if(df==null){  
            df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
            threadLocal.set(df);  
        }  
        return df;  
    }  

    public static String formatDate(Date date) throws ParseException {
        return getDateFormat().format(date);
    }

    public static Date parse(String strDate) throws ParseException {
        return getDateFormat().parse(strDate);
    }   
}

使用说明

方法一二 虽对耗资源,但都是微乎其微的基本可以满足日常需求;方法三 对性能有极致的要求的可以用 ThreadLocal


   版权声明:本文为原创文章,版权归本站所有,欢迎分享本文,转载请保留出处!

发表留言

人生在世,错别字在所难免,无需纠正。

icon_mrgreen.gificon_neutral.gificon_twisted.gificon_arrow.gificon_eek.gificon_smile.gificon_confused.gificon_cool.gificon_evil.gificon_biggrin.gificon_idea.gificon_redface.gificon_razz.gificon_rolleyes.gificon_wink.gificon_cry.gificon_surprised.gificon_lol.gificon_mad.gificon_sad.gificon_exclaim.gificon_question.gif