Thread-safe java.text.SimpleDateFormat format and parse
paulddraper at gmail.com
Sat Jun 27 07:36:20 UTC 2015
While it's often understood that SimpleDateFormat isn't thread safe with
its setters, etc. it is frequently incorrectly assumed (despite the docs)
that since format() and parse() do not mutate the object in a visible way,
they can be called from multiple threads.
The rationale is akin to calling ArrayList#get or HashMap#get from multiple
threads. The entire class is not thread-safe, but you can call that
non-mutating accessor from multiple threads without issue.
The trouble is that SimpleDateFormat has a private Calendar instance
variable, which is mutated during the format() and parse() methods.
This is a very common mistake. There is a project whose entire purpose is a
thread-safe formatter: https://code.google.com/p/safe-simple-date-format/
And Apache Commons and Joda Time provide similar classes.
Currently, users of SimpleDateFormat have to synchronize format() and
parse(), or use a separate SimpleDateFormat for every thread.
Or, too commonly, do neither and have a relatively unobvious race condition.
Making format() and parse() calls thread-safe would require either using a
local Calendar variable -- one instance per call -- or using a thread-local
Calendar -- one instance per thread. The former option seems the best.
The change would be fully backwards compatible. I have profiled a change
with a local Calendar variable, and measured no difference in the
performance (format and parse are by their nature rather involved methods
to begin with).
This change would improve the intuitive behavior of SimpleDateFormat and
eliminate one of the most common mistakes of JDK users.
More information about the jdk9-dev