09 9月 2010

Improve SimpleDateFormat performance

很久之前,承接了一個寫了一半的案子,自專案開始可以測試起就有一個問題,日期時間資料輸出會偶爾有幾筆顯示為很怪的日期,例如是1977/XX/XX,2032/XX/XX,但是怎麼寫Unit Test就是找不出怎麼發生的,當時年紀小,不知道SimpleDateFormat並非Thread Safe,當時在專案最後被逼得花了五天的時間,就是在找這個問題怎麼能重現,最後突然看到Java Doc裡的說明,真的差點流下淚來.....

但是知道SimpleDateFormat不是ThreadSafe後又有另一個問題,要產生一個SimpleDateFormat物件是頗花Resource的,因為裡面包了一個Calendar物件,最初以為使用Clone可以減少消耗Resource,但最後想到,雖然不是Tread Safe,那就讓一個Thread只有一個SimpleDateFormat Instance就好.... 是的,這是我知道有ThreadLocal這東西後才算解決。

簡單的例子如下

public  abstract  class DateUtils {
  private  static  final  Logger logger  = LoggerFactory.getLogger(DateUtils.class ); 
   
  private  static  ThreadLocal<simpledateformat> defaultDateFormat  = new  ThreadLocal<simpledateformat>(); 
   
  public  static  final  SimpleDateFormat getDefaultDateFormat() { 
   if  (null  == defaultDateFormat .get()) { 
    defaultDateFormat .set(new  SimpleDateFormat("yyyy/MM/dd" )); 
   } 
    
    return   defaultDateFormat.get();  
  } 
   
  public  static  final  Date pareseDate(String date) { 
   Date result = null ; 
   try  { 
    result = getDefaultDateFormat().parse(date); 
   } catch  (ParseException e) { 
     logger .error( "Can't parse {} to Date", date);  
   } 
    
   return  result; 
  } 
   
  public  static  final  String formatDate(Date date) { 
   return  getDefaultDateFormat().format(date); 
  } 
} 
這樣就得以解決Thread Safe與Resource的問題