SimpleDateFormat 为什么不是线程安全的?
在看SimpleDataFormat 源码时,提到说SimpleDataFormat不是线程安全的。
* 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.
这是因为里面用了Calendar 这个成员变量来实现SimpleDataFormat,并且在Parse 和Format的时候对Calendar 进行了修改,calendar.clear(),calendar.setTime(date);
所以当SimpleDataFormat使用在多线程的环境中,我们要特别小心,有三种方法来解决这个问题:
1)每次使用时,都创建一个新的SimpleDateFormat实例。如果使用不是很频繁时,可以使用此方法,这样可以降低创建新对象的开销。
2)使用同步:
不过,当线程较多时,当一个线程调用该方法时,其他想要调用此方法的线程就要block,这样的操作也会一定程度上影响性能。
3)就是使用ThreadLocal,来确保每个线程只有一个实例
如:
class SafeDateForamt {
static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
@Override
protected synchronized DateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd");
}
};
public static Date parse(String dateStr) throws ParseException {
return threadLocal.get().parse(dateStr);
}
public static String format(Date date) {
return threadLocal.get().format(date);
}
}