在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); } }