-4

我有以下代码:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TimeZone tz2 = TimeZone.getTimeZone("GMT");
dateFormat.setTimeZone(tz2);
String aDate = "2012-05-02 23:59:59";

for(int i=0 ; i<1000; i++){
        dateFormat.setLenient(false);
        ParsePosition p = new ParsePosition(0);
        Date date = dateFormat.parse(aDate, p);
        java.sql.Date sqlDate = null;
        if (p.getIndex() != aDate.length())
           throw new RuntimeException("just a test");

}

经过多次测试,它非常陌生。基本上,它永远不会完全完成,它非常随机地遇到异常。

你看代码应该是正确的,但是:当它可能i是 500 或者i是 799 或者i是 988 时它遇到了异常(这里只是举一些例子,意味着它在 = 0 时没有发生i,它实际上已经完成了一些圈子),异常可能会在 Datedate = dateFormat.parse(aDate, p);或 line中抛出throw new RuntimeException("just a test");

每个人都可以建议我有什么问题吗?

4

3 回答 3

3

SimpleDateFormat.parse()使用调用的实例变量calendar从字符串构建日期。如果两个线程试图同时解析,calendar变量会被破坏,你会得到错误的结果。

使变量不是静态的不一定有帮助,因为两个线程仍然可以使用同一个控制器。更好的解决方案是在每次解析日期时创建一个新的 DateFormat 对象,或者使用线程本地存储。更好的是,使用具有线程安全解析器的JodaTime 。

使用 SDF 时还要考虑以下几点。

  1. 创建 SimpleDateFormat 是昂贵的。除非很少使用,否则不要使用它。

  2. 好的,如果你能忍受一点阻塞。如果 formatDate() 使用不多,请使用。

  3. 如果您重用线程(线程池),则最快的选择。使用比 2 更多的内存,并且具有更高的启动开销。

对于应用程序 2. 和 3. 都是可行的选择。哪个最适合您的情况取决于您的用例。提防过早的优化。仅当您认为这是一个问题时才这样做。

对于第 3 方将使用的库,我将使用选项 3。

于 2012-05-18T17:45:29.810 回答
2

即使重新运行 20 次,您的代码也能正常工作。因此,让我们猜测一下您的真实SSCCE 可能是什么样子:

public static void main(String[] args) {
  final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
  dateFormat.setLenient(false);
  final String aDate = "2012-05-02 23:59:59";
  for (int i = 0; i < 2; i++)
    new Thread() { public void run() {
      for (int i = 0; i < 1000; i++) {
        ParsePosition p = new ParsePosition(0);
        dateFormat.parse(aDate, p);
        if (p.getIndex() != aDate.length())
          throw new RuntimeException("just a test");
      }
      System.out.println("Done");
    }}.start();
}

这或多或少与您描述的方式不同,原因很明显。听听@Bhavik Ambani 的建议,他正在为您介绍这一点。

于 2012-05-18T17:54:26.487 回答
0

p.getIndex() != aDate.length()

此语句返回 true,这意味着当您解析日期时您没有使用整个字符串 aDate,这意味着 aDate 要么有时区,要么还有其他信息

于 2012-05-18T17:45:39.580 回答