SimpleDateFormat 的線程安全問題

SimpleDateFormat 的作者在源碼中就提到:

* Date formats are not synchronized.
* It is recommended to create separate format instances for each thread.
* If multiple threads access a format concurrently, it must be synchronized
* externally.

Date formats 不是同步的,需要對每個單獨的線程創建各自的實例。如果多線程同時

使用同一個format的話,必須同步。

所以在使用SimpleDateFormat的時候就的特別注意,以下幾種方式是保證線程安全

的使用方式:

一,使用的時候才創建對象:

    public static String formatDate(Date date)throws ParseException{
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        return simpleDateFormat.format(date);
    }

    public static Date parse(String dateString)throws ParseException{
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        return simpleDateFormat.parse(dateString);
    }

由於每次都是新建的對象,則可避免線程共享出現線程安全問題,但是頻繁的創建銷燬對象開銷過大。

 

二,使用synchronized進行同步。

 public  static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

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

    public static Date parse(String dateString)throws ParseException{
        synchronized (SIMPLE_DATE_FORMAT){
            return SIMPLE_DATE_FORMAT.parse(dateString);
        }
    }

由於同步所以線程安全,但是很明顯多個線阻塞性能不佳。

三,使用ThreadLocal。

private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(){
      @Override
      protected DateFormat initialValue() {
          return new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
      }
  };

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

    public static Date parse(String dateString)throws ParseException{
        return threadLocal.get().parse(dateString);
    }

這種用法也是《阿里巴巴開發手冊》的推薦用法。

四,使用1.8新的線程安全的api

private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");

    public static String formatDate(LocalDateTime date)throws ParseException{
        return FORMATTER.format(date);
    }

    public static LocalDateTime parse(String dateString)throws ParseException{
        return LocalDateTime.parse(dateString,FORMATTER);
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章