很久之前,承接了一個寫了一半的案子,自專案開始可以測試起就有一個問題,日期時間資料輸出會偶爾有幾筆顯示為很怪的日期,例如是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的問題