Java SimpleDateFormat的奇怪ArrayIndexOutOfBoundsException

lul*_*u88 16 java simpledateformat indexoutofboundsexception

我们运行Java 1.4.

我们有这个方法:

static SimpleDateFormat xmlFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

public static Date fromXml(String xmlDateTime) {
    ParsePosition pp = new ParsePosition(0);
    return xmlFormatter.parse(xmlDateTime, pp);
}
Run Code Online (Sandbox Code Playgroud)

其中xmlDateTime = 2013-08-22T16:03:00的例子.这一直有效,但突然停止了!

我们现在得到这个例外:

java.lang.ArrayIndexOutOfBoundsException: -1
at java.text.DigitList.fitsIntoLong(DigitList.java:170)
at java.text.DecimalFormat.parse(DecimalFormat.java:1064)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1381)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1159) 
Run Code Online (Sandbox Code Playgroud)

我试图通过使用不同的日期格式在单元测试中重现这一点,即:

2013-08-22T16:03:00
2013-08-22 16:03:00
Run Code Online (Sandbox Code Playgroud)

但没有运气!有任何想法吗?

Boh*_*ian 37

这是一个鲜为人知的事实,SimpleDateFormat不是线程安全的!

不是一个错误:javadoc记录了这种行为:

日期格式未同步.建议为每个线程创建单独的格式实例.如果多个线程同时访问格式,则必须在外部进行同步.

每次需要时创建一个实例,或者如果性能是一个真正的问题,您可以尝试使用ThreadLocal为每个需要一个的线程存储实例.


不要感觉不好:我完全倾向于"优化"(重用一个常量实例),令我惊讶的是,每次都必须实例化一个新实例.

  • @android它不是线程安全的,因为编写它的白痴决定不使其线程安全。然而,Java 8 的“DateTimeFormatter”等*是*线程安全的。 (2认同)

bow*_*ore 5

看起来像这个错误报告.根本原因被诊断为DecimalFormat根本不是线程安全的.

所以你不应该SimpleDateFormat在不同的线程上使用相同的实例,因为它DecimalFormat仍然不是线程安全的.

您可以使用ThreadLocal每个线程使用自己的实例.