Non-thread-safe date/time fields should not be public and staticJAVA-E1024
Avoid storing non-thread-safe java.util
date/time API classes in public static fields.
These classes are not designed to be used directly over multiple threads and issues such as race conditions or spurious crashes may occur.
This issue will be reported if a public static
field is found having any of the following types:
Calendar
is particularly insidious in this, as its documentation makes no mention of its lack of thread safety.
Bad Practice
Consider the example below, which uses Calendar
(the same principle applies to SimpleDateFormat
as well). Because CAL_INSTANCE
is public
, it can be accessed by any external code.
public static final Calendar CAL_INSTANCE = ...;
Modifying (or even accessing fields of) a Calendar
instance will mutate it, and such mutations can cause unintended state changes on other threads.
Recommended
If a single global Calendar
instance is absolutely required, make sure to keep the field private
, and predefine all possible actions that will be performed with the object as synchronized methods. This reduces the chances of race conditions occurring due to unsynchronized usage of the specific calendar instance.
private static final Object LOCK = new Object();
private static final Calendar cal = ...;
public Date getDateAfter(int days) {
synchronized(LOCK) {
cal.add(Calendar.DAY, days);
Date date = cal.getTime();
cal.add(Calendar.DAY, -days);
return date;
}
}
If each thread requires a persistent instance, consider wrapping the field in a ThreadLocal
instead. This will allow for keeping the field public
and static
while still preserving thread safety.
public static ThreadLocal<Calendar> = ThreadLocal.withInitial(() -> Calendar.getInstance());
If a global instance is not required, just use an instance value, or create a new instance on demand.
Alternatives
If possible, consider using a better date/time API such as java.time
(For Java versions 8 and above) or Joda-time (For Java versions 7 and below), which do not have such thread safety issues.
References
- Oracle Java 17 JavaDocs -
java.util.Calendar
- Oracle Java 17 JavaDocs -
java.text.SimpleDateFormat
- Stackoverflow - Is
java.util.Calendar
thread-safe or not?