Friday, March 23, 2012

SimpleDateFormat in Java is not Thread-Safe Use Carefully

SimpleDateFormat in Java  very common and used to format Date to String and parse String into Date in Java but it can cause very subtle and hard to debug issues if not used carefully because DateFormat and SimpleDateFormat both are not thread-safe and buggy. call to format() and parse() method mutate state of DateFormat class and should be synchronized externally in order to avoid any issue. here are few points which you should take care while using SimpleDateFormat in Java:

SimpleDateFormat in Java is not Thread-Safe

1) Use local DateFormat or SimpleDateFormat objects for converting or formatting dates in Java. Making them local ensure that they will not be shared between multiple Threads.

2) If you are sharing Date for SimpleDateFormat class in Java then you need to externally synchronize
call to format() and parse() method as they mutate state of DateFormat object and can create subtle and hard
to fix bugs while formatting Strings or creating dates in Java. Best is to avoid sharing of DateFormat class altogether.

3) If you have option use JODA date time library for your date and time related operation. its easy to understand and portable with Java Date API and solves all thread-safety issues associated with SimpleDateFormat in Java.

4) Another good alternative of SimpleDateFormat in Java is Apaches' commons.lang package which hold a class called  FastDateFormat utility class and thread-safe alternative of SimpleDateFormat in Java.

5) Another approach of synchronizing DateFormat and SimpleDateFormat is using ThreadLocal, which create SimpleDateFormat on per Thread basis but it can be source of severe memory leak and java.lang.OutOfMemoryError if not used carefully. so avoid until you don't have any other option.

That’s all on SimpleDateFormat in Java. Many people has pointed out flaw on design of Format class but unfortunately Sun or Oracle has not addressed them in any release not even in JDK7. SimpleDateFormat is still first choice because of its availability on standard library but should be used carefully.

Other Java tutorials you may like

12 comments :

Ricardo Zuasti said...

Nice one, didn't know about this and indeed it can be *very* relevant. Oracle should really address this ASAP, SimpleDateFormat is widely used in multi-threaded apps...

I guess there is no reason to use it over FastDateFormat.

St├ęphan Mestach said...

I've simply dropped jdk date classes in favor to jodatime from all our java projects enforcing this rule
with sonar :

http://mestachs.wordpress.com/2012/03/17/dangerous-can-be-dating-in-java-joda-to-the-rescue/

Javin @ serialization interview questions said...

Thanks for your comment Stephan. Indeed many people uses JodaTime in place of SimpleDateFormat in Java. those who stick around only because of not introducing new library.

Javin @ multi-threading interview question said...

@Recordo, Thanks for your comments. If Oracle can make SimpleDateFormat better and bug free that would be best. Instead of introducing lot of new library in JDK7, they could have just address this as well.

Anonymous said...

Note that even if you do synchronize externally to use SimpleDateFormat in a multi-threaded environment, there's no way to serialize a SimpleDateFormat in a thread-safe way, because it holds a reference to a Calendar, which mutates its internal state during de-/serialization
(see Calendar#writeObject and Calendar#readObject, the 'zone' field is changed).

Javin @ serialization interview questions said...

Good point @Anonymous. Thanks for bringing point of Serialization on SimpleDateFormat.

Daniel Schneller said...

This is a topic Oracle/Sun are probably never going to address. I wrote about it 5 years ago http://www.danielschneller.com/2007/04/calendar-dateformat-and-multi-threading.html and still there is no change. If you do not want to move to Joda (or can't), around the same time I contributed a detector to FindBugs that looks for static fields of type DateFormat or Calendar (and their respective subclasses) and issues a warning in the thread-safety category. Make sure to have FindBugs run and check this and other stuff in your build process.

Javin @ HashMap vs HashSet said...

@Daniel, Thanks for your comment. you may be right because its known issue from long time. many of programmer have stopped using SimpleDateFormat due to its thread-safety issue and as you mentioned static code analyzer also has pattern for detecting static SimpleDateFormat among code. It's just unfortunate Sun doesn't address it.

Anonymous said...

Can anyone give a working code example for "call to format() and parse() method should be synchronized externally"? It would be a huge help for novices like me.

Javin @ blocking method in java said...

@Anonymous, It would be similar to how you synchronize shared object for mutual exclusion. here is a psuedo code

DateFormat localFormat; //shared
synchronized(localFormat){
localFormat.format();
}

Chas Honton said...

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

El Santo said...

ThreadLocal + SimpleDateFormat = SimpleDateFormatThreadSafe

https://gist.github.com/pablomoretti/9748230

Post a Comment