Common mistake with Java’s SimpleDateFormat and Calendar in multi-threading environments
Common mistake with SimpleDateFormat and Calendar in multi-threading environments
Sample code from various projects I stumbled upon recently (I skipped some lines that are not relevant to this article):
public class SomeEventSerializer {
protected static final String javaDateFormat = ..private static final SimpleDateFormat format = new SimpleDateFormat(javaDateFormat);
public void serialize(…){
event.getDate() == null ? “-” : format.format(event.getDate()));Another one:
class SomeResource {
private static SimpleDateFormat format = new SimpleDateFormat(“yyyy-MM-dd”);public Response loadSomething(…) {
format.parse(startdate);Another one:
public class SomeActionHelper {
private static final SimpleDateFormat FORMAT_DATE = new SimpleDateFormat(“MM/dd/yyyy”);public static String getHtml(….) {
StringBuilder builder = new StringBuilder();
builder
.append(FORMAT_DATE.format(string.getStart()))
.append(FORMAT_DATE.format(string.getEnd()));Javadoc for SimpleDateFormat class states that it is not thread-safe: SimpleDateFormat (Java Platform SE 7 )
Synchronization
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.
Which means that multiple threads calling FORMAT_DATE.format() will receive corrupted text at random times.
Same with java.util.Calendar, except its javadoc does not say anything about thread-safety.
Possible solutions are:
- Use Java 8! These problems are solved in JDK8: DateTimeFormatter (Java Platform SE 8 )
- if you can’t use Java 8 — synchronize access to the formatter.
- again — if you can’t use Java 8 — use a thread-safe library for date processing like Joda Time.
- if you can’t use Java 8 and everything else fails — use ThreadLocal (do not do this unless you really understand what you are doing)
In general, whenever you use any class in a multi-threading environment (meaning most of the time really) you should be aware whether or not it is thread-safe. If the class’ javadoc does not explicitly state that the class is thread-safe, it is probably not.
Here is a nicely formatted (no pun intended, gee) explanation with code samples: multithreading — “Java DateFormat is not threadsafe” what does this leads to? — Stack Overflow