DateFormats不是线程安全的,意味着它们维护状态的内部表示。如果多个线程同时访问同一个实例,在静态上下文中使用它们可能会产生一些很奇怪的错误。
我的建议是让你的变量局部到你使用它们,而不是使它们的类的静态属性。看起来当你初始化类时,你可能会这样做,所以你可以在构造函数中这样做:
public class MyClass {
private String fileName;
public MyClass() {
final Date today = Calendar.getInstance().getTime();
final DateFormat yymmdd = new SimpleDateFormat("yyMMdd");
this.fileName = "file_" + yymmdd.format(TODAY);
}
...
}
如果你需要在多个地方使用格式器,你可能只是使模式静态final,并创建一个新的本地DateFormat需要时:
public class MyClass {
private static final String FILENAME_DATE_PATTERN = "yyMMdd";
public void myMethod() {
final DateFormat format = new SimpleDateFormat(FILENAME_DATE_PATTERN);
// do some formatting
}
}
As the JavaDoc states, DateFormats are
inherently unsafe for multithreaded
use. The detector has found a call to
an instance of DateFormat that has
been obtained via a static field. This
looks suspicous.
For more information on this see Sun
Bug #6231579 and Sun Bug #6178997.
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.
Jack Leow’s answer也有一个好点,关于你的静态使用“TODAY”的语义。
除此之外,我实际上在高流量的生产环境中看到了这种情况,这是一个很混乱的事情,首先调试;所以在我的经验中,FindBugs警告实际上是一个有用的建议(不像其他一些静态分析规则,有时看起来是nitpicky)。