我一直试图找出这个bug几天。我已将问题缩小到测试用例,如下所示。同样,这是导致错误发生的测试用例。该功能(此时)不是实用的功能,只是试图找出错误。
服务器正在运行: - 雄猫6 - OpenJDK 1.6.0_17 - CentOS 5.5
我有一个简单的类文件,其中包含以下方法静态方法和静态变量声明:
public static java.text.SimpleDateFormat displayDateSDF1 = new java.text.SimpleDateFormat("MM/dd/yyyy");
public static java.util.Date getSubDateMini(String inputDate)
{
java.util.Date testObj = null;
try
{
testObj = displayDateSDF1.parse("01/01/2000") ;
}
catch (Exception e)
{
}
return testObj;
}
在Tomcat中进行测试:
当我运行这种方法时,我希望每次都得到相同的结果,对吧?但是,如果我从JSP调用此方法,我会获得Date对象的预期结果,其值为1/1/2000,大约为99.9%。但是,有时我会使用看似随机的日期值传回一个意外的数据对象。
为了测试这个,我创建了一个JSP,其中包含以下代码段:
for (int i=0; i<200000;i++)
{
java.util.Date testObjLib = TestDate.getSubDateMini("") ;
if (testObjLib!=null&&!testObjLib.toString().equalsIgnoreCase("Sat Jan 01 00:00:00 PST 2000"))
{
out.print("<br>"+testObjLib+"");
}
}
出现的一些日期如下:
Wed Jan 01 00:00:00 PST 1
8月01日星期五00:00:00 PDT 2166
在200,000次运行中,我得到大约50个错误的日期,错误率为~0.025%,但它也是随机的。我用10次迭代运行这个循环并收到错误。有时它以200,000运行循环并且所有日期看起来都很好。
在Java中测试:
通过CentOS中的控制台/终端应用程序以相同的循环运行此循环,我还没有看到此错误发生。我将循环增加到10,000,000并且到目前为止还没有错误的结果。
我可以理解内存不足或某些抛出错误(这会导致空值)但不会损坏/不一致数据。我从头开始用Tomcat 6构建了一个新服务器,并尝试了Tomcat 5.5,两者都有相同的结果。我没有尝试过Tomcat 7。
有什么建议吗?
答案 0 :(得分:5)
SimpleDateFormat
不是线程安全的。
这意味着当从多个线程访问它时,可以观察到意外的结果。并且tomcat正在为来自单独线程的每个请求提供服务,因此每当两个请求同时发出时,就会出现问题。
您有多种选择:
SimpleDateFormat
(而不是使其成为static
)ThreadLocal
进行存储。DateTimeFormat
是线程安全的。