Tomcat 5.5和6.0中的数据损坏问题运行function

我一直在试图找出这个bug几天。 我已经把这个问题缩小到一个testing案例如下。 再次,这是一个导致错误发生的testing用例。 function(在这一点上)不是一个实际的,但只是想弄清楚这个错误。

服务器正在运行: – Tomcat 6 – OpenJDK 1.6.0_17 – CentOS 5.5

我有一个简单的类文件与以下方法静态方法和静态variables声明:

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中testing:

当我运行这个方法时,我希望每次都得到相同的结果,对吧? 不过,如果我从JSP中调用这个方法,我会得到约99.9%的时间值为1/1/2000的Date对象的预期结果。 但是,有时我会收到一个意外的数据对象,并传递一个看似随机的date值。

为了testing这个,我创build了一个包含以下代码段的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+""); } } 

出现的date如下:

1月1日星期三00:00:00 PST 1

星期五8月01日00:00:00 PDT 2166

在20万次运行中,我得到了约50个错误date,错误率为〜0.025%,但又是随机的。 我已经运行这个循环10迭代,并收到一个错误。 有时候它运行循环20万,所有的date看起来不错。

在Java中testing:

在CentOS中通过一个控制台/terminal应用程序运行这个循环,我没有看到这个错误发生。 我把这个循环增加到了10,000,000,迄今为止还没有错误的结果。


我可以理解的内存或一些抛出的错误(这将导致一个空值),但没有损坏/不一致的数据。 我用Tomcat 6从零开始构build了一个新的服务器,并尝试了Tomcat 5.5,两者都有相同的结果。 我没有尝试过Tomcat 7。

有什么build议么?

SimpleDateFormat不是线程安全的。

这意味着当从多个线程访问它时,可以观察到意想不到的结果。 而tomcat正在从一个单独的线程提供每个请求,所以无论何时两个请求同时发生,问题就会出现。

你有很多选择:

  • 在方法的每个调用上实例化SimpleDateFormat (而不是static
  • 如果您需要每个线程多于一次的格式,请使用ThreadLocal来存储它。
  • 或者使用joda-time,其中DateTimeFormat是线程安全的。