我一直在试图找出这个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
来存储它。 DateTimeFormat
是线程安全的。