I have the following code:
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");
}
After testing plenty of times, it was very stranger. Basically, it never be finished completely, it ran into exception very randomly.
You see the code should be correct, but: it ran into exception when maybe i is 500 or i is 799 or i is 988(just take some examples here, means it was not getting happened when i = 0, it actually has finished some circles), the exception may get thrown in either line Date date = dateFormat.parse(aDate, p); or line throw new RuntimeException("just a test");;
Can everybody advice me whats wrong?
SimpleDateFormat.parse()uses an instance variable calledcalendarto build the date from the string. If two threads try to parse at the same time, thecalendarvariable will get clobbered and you’ll get wrong results.Making the variable not static won’t necessarily help, since two threads could still be using the same controller. A better solution is to either create a new DateFormat object each time you parse a date, or use thread local storage. Better still, use JodaTime which has thread safe parsers.
Also consider the following points while using SDF.
Creating SimpleDateFormat is expensive. Don’t use this unless it’s done seldom.
OK if you can live with a bit of blocking. Use if formatDate() is not used much.
Fastest option IF you reuse threads (thread pool). Uses more memory than 2. and has higher startup overhead.
For applications both 2. and 3. are viable options. Which is best for your case depends on your use case. Beware of premature optimization. Only do it if you believe this is an issue.
For libraries that would be used by 3rd party I’d use option 3.