Question
Why shouldn't I call methods of static java.text.DateFormat?
private static final Date TODAY = Calendar.getInstance().getTime();
private static final DateFormat yymmdd = new SimpleDateFormat("yyMMdd");
private String fileName = "file_" + yymmdd.format(TODAY);
Answer
Using static methods from java.text.DateFormat can introduce risks, especially in multi-threaded environments. This is primarily due to the non-thread-safe nature of SimpleDateFormat, which can lead to unexpected behavior or errors when accessed from multiple threads.
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Calendar;
import java.util.concurrent.atomic.AtomicInteger;
public class DateUtils {
private static final ThreadLocal<DateFormat> dateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyMMdd"));
public static String getFormattedDate() {
Date today = Calendar.getInstance().getTime();
return "file_" + dateFormat.get().format(today);
}
}
Causes
- SimpleDateFormat is not thread-safe, which can lead to data corruption when accessed concurrently.
- Instances of SimpleDateFormat maintain their internal state, which can be modified during formatting, causing inaccuracies.
- Find Bugs may flag this because static fields can lead to shared state issues across different classes or threads.
Solutions
- Use ThreadLocal to maintain separate instances of SimpleDateFormat for each thread.
- Switch to java.time.format.DateTimeFormatter from Java 8, which is immutable and thread-safe.
- Create a utility method for date formatting that ensures each call uses a fresh instance of SimpleDateFormat.
Common Mistakes
Mistake: Using a single instance of SimpleDateFormat across multiple threads.
Solution: Implement ThreadLocal to ensure each thread uses its unique instance.
Mistake: Neglecting the potential for concurrent modification of static date formatters.
Solution: Prefer java.time classes which are designed to be immutable and thread-safe.
Helpers
- java.text.DateFormat
- SimpleDateFormat
- thread safety
- Java date formatting
- FindBugs static method warning
- java.time.format.DateTimeFormatter