有人都喜欢把SimpleDateFormat实例用在多线程环境下,
有两种情况:
1) 定义成类的静态成员
Private static final SimpleDateFormat sdf = new SimpleDateFormat(“yyyyMMdd”);
2) 定义成类的成员
Private SimpleDateFormat sdf = new SimpleDateFormat(“yyyyMMdd”);
这两种情况都有可能被多个线程使用, 随时都有可能出错.
见附件的一个测试例子, 两个线程不停的调用, 大概十几次就有可能一次出错.
原因:
因为SimpleDateFormat处理复杂,Jdk的实现中使用了成员变量来传递参数,这个就造成在多线程的时候会出现错误。
Doc:
实际上, JDK 1.4,JDK5.0, JDK 6.0 都在文档中明确说了是线程不安全的, 包括 DateFormat, MessageFormat, NumberFormat, DecimalFormat, SimpleDateFormat 等等.
后果:
1) 从附件中测试的例子可以看出, 很容易就线程间的数据乱掉了.
2) 网上有说在多线程环境下执行会抛exception的情况.
3) 用的很频繁, 导致内存泄露, 很容易就出现内存溢出.
安全的用法:
1) 每次用的时候new 一个实例.
public static final String DATE_FORMAT= "yyyy-MM-dd";
public static String formatDate(Date date){
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
return sdf.format(date);
}
2) 所有用到同一个SimpleDateFormat实例的地方用synchronized进行同步.