SimpleDateFormat
是非线程安全的,在并发下碰到的案例见过好几次了。若场景对性能要求很高,创建大量生命周期很短暂的实例对象也是不小开销(主要是SimpleDateFormat内部比较复杂),可以考虑采用ThreadLocal
来优化,以前曾见到过这种优化方式,忘了出处,在tomcat的代码里也有这样的用法,下面代码是tomcat7的DateTool工具类里的:
public static final ThreadLocal<DateFormat> rfc1123Format = new ThreadLocal<DateFormat>() {
@Override
public DateFormat initialValue() {
DateFormat result = new SimpleDateFormat(RFC1123_PATTERN, Locale.US);
result.setTimeZone(GMT_ZONE);
return result;
}
};
调用的时候,每个线程可以通过rfc1123Format.get().format(...)
来使用。不过tomcat8里已经删除了这个类。
我们一个同事, 在做spark计算时, 遇到一个BUG…查到最后发现就是这个格式化非线程安全. 后来他就用的threadlocal解决的.
嗯,这招有效的
之前一个老项目要国际化,没招只能用 ThreadLocal存储Locale信息, 总觉得不踏实,又说不出哪里不好,ThreadLocal是不是很多场景下的无奈之举?
threadLocal只能用在线程数是固定的场景