三种方法解决SimpleDateFormat的线程不安全性

在Java项目中,咱们一般会本身写一个DateUtil类,处理日期和字符串的转换。以下

  
 

     
public class DateUtil{ 
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); 
    public static formatDateToYYYYMMDDStr(Date date){
        return sdf.format(date); 
    }
 
    public static formatYYYYMMDDStrToDate(String str){
        return sdf.parse(str); 
    }
}

 

然而,因为SimpleDateFormat类不是线程安全的,因此在多线程的环境下,每每会出现意想不到的结果。

有三种方法能够解决以上问题。

1)每次使用时,都建立一个新的SimpleDateFormat实例。若是使用不是很频繁时,能够使用此方法,这样能够下降建立新对象的开销。

2)使用同步:

  
public class DateUtil{ 
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); 
    private Date parse(String dateStr) throws ParseException{ 
        synchronized (sdf){ 
            return sdf.parse(dateStr); 
        }
     } 
    private String format(Date date){ 
        synchronized (sdf){ 
            return sdf.format(dateStr); 
        }
     }
 }

不过,当线程较多时,当一个线程调用该方法时,其余想要调用此方法的线程就要block,这样的操做也会必定程度上影响性能。

我的最推荐的是第三种方法,那就是借助ThreadLocal对象每一个线程只建立一个实例。

  

      
public class DateUtil { 
    private static final String DATE_FORMAT = " yyyyMMdd " ; 
    @SuppressWarnings( " rawtypes " ) 
    private static ThreadLocal threadLocal = new ThreadLocal() { 
        protected synchronized Object initialValue() { 
            return new SimpleDateFormat(DATE_FORMAT); 
        } 
    }; 
    public static DateFormat getDateFormat() { 
        return (DateFormat) threadLocal.get(); 
    } 
    public static Date parse(String textDate) throws ParseException { 
        return getDateFormat().parse(textDate); 
    }
 }
相关文章
相关标签/搜索