Strange ArrayIndexOutOfBoundsException for Java SimpleDateFormat

纵饮孤独 提交于 2019-12-05 14:23:07

问题


We run Java 1.4.

We have this method:

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);
}

Where xmlDateTime = 2013-08-22T16:03:00 for example. This has been working, but suddenly stopped!

We now get this exception:

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) 

I have tried to reproduce this in a Unit Test by using different date formats, ie:

2013-08-22T16:03:00
2013-08-22 16:03:00

But no luck! Any ideas?


回答1:


It is a little known fact that SimpleDateFormat is not threadsafe!

It is not a bug: The javadoc documents this behaviour:

Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

Create an instance every time you need one, or if performance is a real issue, you could try using ThreadLocal to store an instance for each thread that needs one.


Don't feel bad: I fell for exactly this "optimization" (to reuse a single constant instance), and to my amazement, had to instantiate a new instance every time.




回答2:


Looks like this bug report. The underlying reason was diagnosed to be that DecimalFormat simply isn't thread safe.

So you should not use the same SimpleDateFormat instance on different threads, since it, and DecimalFormat still aren't thread safe.

You could use ThreadLocal to have each thread use its own instance.




回答3:


A simple way to create instance each time, a local/scope variable instead of global variable, it works for me

private void test {
    SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(pattern, Locale.ENGLISH);
    // Do somethings
}



回答4:


Try using Commons Lang 3.x FastDateParser and FastDateFormat. These classes are thread safe and faster than SimpleDateFormat. They also support the same format/parse pattern specifications as SimpleDateFormat.



来源:https://stackoverflow.com/questions/18383251/strange-arrayindexoutofboundsexception-for-java-simpledateformat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!