代碼里邊偶然發(fā)現(xiàn)一個bug冕广,代碼如下高氮,
public class DateUtil{
// format默認格式
private static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
protected synchronized DateFormat initialValue() {
return new SimpleDateFormat(DATE_FORMAT);
}
};
// 根據(jù)傳入的format生成對應(yīng)的SimpleDateFormat
public static SimpleDateFormat getDateFormatInstance(String format) {
if (null != format && !format.equals("")) {
DATE_FORMAT = format;
} else {
DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
}
return (SimpleDateFormat) threadLocal.get();
}
}
這段代碼是用來做日期的format的,考慮到性能問題对妄,這里采用了ThreadLocal來獲取SimpleDateFormat,而不是采用傳統(tǒng)的new方式敢朱。在容器加載上述代碼的時候剪菱,靜態(tài)變量threadLocal 會被初始化,DateFormat的格式為默認拴签,即"yyyy-MM-dd HH:mm:ss"孝常,所以如果當(dāng)我們這樣使用該工具類的時候就出了問題,如下:
DateUtil.getDateFormatInstance("yyyy-MM-dd").format(Calendar.getInstance().getTime());
得到的日期字符串格式不是我們想要的"yyyy-MM-dd"格式蚓哩,而是"yyyy-MM-dd HH:mm:ss"默認格式构灸。這個不難理解,因為threadLocal 只初始化了一次杖剪,并且DateFormat為默認格式冻押。如果想format不同格式的日期驰贷,正確的姿勢是這樣的:
public class DateUtil{
private static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
// 鎖對象
private static final Object lockObj = new Object();
private static Map<String, ThreadLocal<SimpleDateFormat>> threadLocalMap = new HashMap<String, ThreadLocal<SimpleDateFormat>>();
public static SimpleDateFormat getDateFormatInstance(final String format) {
ThreadLocal<SimpleDateFormat> tLocal = threadLocalMap.get(format);
if (null == tLocal) {
synchronized (lockObj) {
if (null == tLocal) {
tLocal = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
if (null != format && !format.equals("")) {
DATE_FORMAT = format;
} else {
DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
}
return new SimpleDateFormat(DATE_FORMAT);
};
};
threadLocalMap.put(format, tLocal);
}
}
}
return tLocal.get();
}
}
上邊只是一個ThreadLocal的使用場景和姿勢,那我就在想洛巢,ThreadLocal是什么括袒,可以用來做什么?有什么優(yōu)勢稿茉?
有人這樣解釋的锹锰,我覺得挺好:
ThreadLocal的作用是提供線程內(nèi)的局部變量,這種變量在線程的生命周期內(nèi)起作用漓库,減少同一個線程內(nèi)多個函數(shù)或者組件之間一些公共變量的傳遞的復(fù)雜度恃慧。具體參考[Java并發(fā)包學(xué)習(xí)七]解密ThreadLocal 這篇文章。