One of my daily responsibilities is to look over the code that is checked into our JIRA source base. I look at every commit and check for any obvious mistakes, typos or things that can be instantly improved.
I must admit that in recent months it was and still is quite hard to pick any obvious errors or coding mistakes from our JIRA code. I hardly get to find something major that I would need to report back to the author of that code check-in.
Recently I blogged internally about some minor findings. Some of these were not recent mistakes, rather the code that I recently touched (as part of changing some other parts in JIRA), the old code that exposed some of the caveats of Java that still live inside JIRA source base.
I received a very positive feedback to my post. This blog post also sparked a discussion between developers (including developers from other teams). I would like to sum this discussion up and share it with you.
In my post I suggested to use DateFormat class only locally. The reason behind it is that the implementation of DateFormat class is not thread-safe. As it’s JavaDoc states:
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.
The problem with this class is that it has a state and if you have two or more threads calling methods on the same instance you could get results you would not expect. As commented by Charles Miller:
“SimpleDateFormat’s non-thread-safety can cause some really fun bugs, because the most common symptom is getting correctly formatted output for a totally different date.”
I suggested that the simplest fix for the concurrency problem is to create a new instance each time as needed. This naturally is not the best solution from the performance point of view, but the simplest trade-off for thread safety.
This was rightfully spotted by Adrian Hempel, who suggests to use ThreadLocal to store a reference to DateFormat object. He also warns about premature optimization and adds that this should be only used if a construction of a new object each time becomes a real problem.
Another very good suggestion came from Mark Chaimungkalanont who suggests to use FastDateFormat from Apache Commons Lang package. This class is thread-safe therefore can be happily used across multiple thread.
While we are on the topic of DateFormat objects, it’s worth to mention that these objects are serializable (implement Serializable interface) and it may not be a good idea to store their instances as member variables. As Adrian also mentioned to us:
“A serialised SimpleDateFormat is 36K in size! GregorianCalendar has a similar but lesser problem, making its serialised form 2.3K. The reason is that they both include all their constant data relating to time zone in their serialised forms.”
Ok, I hope I did not bore you too much with this lesson on DateFormat objects. We like to share information, between the developers internally or externally. As we discovered many times it’s a great way to learn more.
If you’d like to work with us, Atlassian is hiring. And don’t be surprised if you happen to be asked about thread-safety of DateFormat objects at the tech interview 🙂