This discussion is archived
8 Replies Latest reply: Mar 1, 2013 10:18 AM by jtahlborn RSS

SimpleDateFormat and Thread safety

user1980584 Newbie
Currently Being Moderated
I have a question with regards to SimpleDateFormat and it's lack of thread safety.

I have a DateUtils class which does a series of date related operations, one among them being parsing wherein this static method takes in a string and parses it to a Date. I have a couple of SimpleDateFormats and this method spins thru' those and returns back a Date as soon as a matching format is found. The problem I'm encountering is that these SimpleDateFormats are being stored in an array that is static (since the method is static - as it is within an util class, had to declare this array as static as well). With this configuration, isn't it true that this poses a threat when multiple threads are running simultaneously? If so, should I use ThreadLocal to make it thread safe? Or, can I somehow remove the "static" declaration and make it work?

Thanks in advance.
  • 1. Re: SimpleDateFormat and Thread safety
    EJP Guru
    Currently Being Moderated
    Well it isn't thread-safe, so you have to do something. Making them instance variables won't fix it though. You either have to synchronize or use ThreadLocal.
  • 2. Re: SimpleDateFormat and Thread safety
    gimbal2 Guru
    Currently Being Moderated
    I wonder what might go wrong when multiple threads use the same formatter? They seem pretty stateless to me once you construct them.
  • 3. Re: SimpleDateFormat and Thread safety
    doremifasollatido Journeyer
    Currently Being Moderated
    gimbal2 wrote:
    I wonder what might go wrong when multiple threads use the same formatter? They seem pretty stateless to me once you construct them.
    If you use the same SimpleDateFormat for formatting in multiple threads, you get output like this (4-digit year, 3-digit day-of-year, 2-digit hour [0-23], 2-digit minute, underscore, numeric count) [this is real output from our system, not a contrived example]:
    [20122860730_0],
    [20122820730_1],
    [20122821600_2],
    [20122821600_3],
    [20122821600_4],
    [20122821600_5]

    The output was supposed to be from Hour 16 Minute 0 of Day 282 (October 8) of 2012 (as correctly seen in the 3rd through 6th entries [count _2 to _5).
    A second thread interfered and an entry from Hour 7 Minute 30 of Day 286 (October 12) appeared for the first (_0) entry in the list (wrong Day, wrong Hour, wrong Minute).
    The second (_1) entry in the list got the correct Day (Day 282), but still had interference from the other thread and got the wrong Hour and Minute (7:30 instead of 16:00).

    This was resolved by using a new SimpleDateFormat for each thread.

    ============
    Apparently, the lack of thread safety comes from the fact that DateFormat (parent class of SimpleDateFormat) has an instance field "calendar" [a java.util.Calendar] that gets manipulated for parsing/formatting.
  • 4. Re: SimpleDateFormat and Thread safety
    user1980584 Newbie
    Currently Being Moderated
    I read up about ThreadLocal and am a bit confused. What it does is essentially give each thread it's own local variable, correct? If that is the case, then how does it differ from just creating an instance variable? Does it give any memory or performance benefits?

    Thanks.
  • 5. Re: SimpleDateFormat and Thread safety
    jtahlborn Expert
    Currently Being Moderated
    user1980584 wrote:
    I read up about ThreadLocal and am a bit confused. What it does is essentially give each thread it's own local variable, correct? If that is the case, then how does it differ from just creating an instance variable? Does it give any memory or performance benefits?
    it depends on the instance in question. if an instance of the object is only used by a single thread, then, yes, using an instance variable will work just fine.

    ThreadLocal is useful for situations where:

    - you have 2 pieces of code running in the same thread which need to share data but have no way of passing a reference directly from one part of the code to the other (often due to limitations in third-party apis)
    - you have a static method/class which is used by multiple threads and you need to store some state which is not shared across threads, but without requiring the caller to maintain the state
  • 6. Re: SimpleDateFormat and Thread safety
    user1980584 Newbie
    Currently Being Moderated
    Thanks. It makes sense.
  • 7. Re: SimpleDateFormat and Thread safety
    gimbal2 Guru
    Currently Being Moderated
    This thread really surprises me, in a bad way. I have stuck formatters in statics for webapps without running into the mentioned issues... but now i am definitely going to experiment.

    On the other hand for years now i have stopped being scared of creating objects so nowadays i dont reuse formatters anymore. This just strengthens my beliefs :)
  • 8. Re: SimpleDateFormat and Thread safety
    jtahlborn Expert
    Currently Being Moderated
    gimbal2 wrote:
    This thread really surprises me, in a bad way. I have stuck formatters in statics for webapps without running into the mentioned issues... but now i am definitely going to experiment.
    That's a shame. this issue came to light a long time ago and is definitely not one of those "theoretical" problems. plenty of people have run into this for real (myself included).
    On the other hand for years now i have stopped being scared of creating objects so nowadays i dont reuse formatters anymore. This just strengthens my beliefs :)
    that is definitely a good place to be, in general. that said, formatters like SimpleDateFormat are not necessarily cheap. they have to parse the given String format each time you create them. if you do a lot of date/time formatting, this could be an issue. obviously, the lesson here is "default to safe" and if you have performance issues, and profiling indicates the formatters as the problem, then (and only then) look into ways to start caching formatters.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points