Calendar.getInstance() thread safe?

Discussion in 'Java' started by endymion, Mar 7, 2010.

  1. endymion

    endymion Guest

    Hi,

    In a multi-threaded application, I encountered problems with dates being
    "reset" to 1970, or being negative when converted into ms since 1970.

    I use Calendar to do operations on dates, and as I see no obvious bug in the
    code, and as the problem occurs randomly and after a certain time, I was
    wondering if that was a multi-threading issue.

    So the question is: Is Calendar.getInstance() thread safe?

    I did not find a satisfying answer searching the web.

    Is there asbolutely no possibility that two (or more) threads calling
    Calendar.getInstance() at the same time get the same Calendar object?

    In my code I do the following:

    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.MINUTE, amount);
    [...]

    Thanks for your answers.

    Christophe B.
     
    endymion, Mar 7, 2010
    #1
    1. Advertising

  2. endymion

    markspace Guest

    endymion wrote:

    > So the question is: Is Calendar.getInstance() thread safe?



    I think you have to assume all methods are thread safe unless there is
    documentation to the contrary. How could you call any method reliably
    unless it was deemed to be safe to do so?


    > In my code I do the following:
    >
    > Calendar calendar = Calendar.getInstance();
    > calendar.add(Calendar.MINUTE, amount);



    "getInstance()" doesn't say it returns a new instance, but I don't see
    how it could not. I think it is more likely that:

    1. "amount" above is set to an incorrect value. Do you range check it?

    2. The "calendar" object is getting set incorrectly after this line
    (i.e., it's in the code you aren't showing us). OBJECTS are never
    thread safe unless you make them so, and that discounts the possibility
    of simple logic errors (i.e., you set the value of "calendar" to a
    negative value somewhere else in your code).


    I think we need to see some code that actually reproduces the problem.
    If you can make an SSCCE that shows us the error, we'll take a look at it.

    http://sscce.org/
     
    markspace, Mar 7, 2010
    #2
    1. Advertising

  3. endymion

    Arne Vajhøj Guest

    On 07-03-2010 11:13, markspace wrote:
    > endymion wrote:
    >> So the question is: Is Calendar.getInstance() thread safe?

    >
    > I think you have to assume all methods are thread safe unless there is
    > documentation to the contrary. How could you call any method reliably
    > unless it was deemed to be safe to do so?


    Maybe for a static method like this. It is not very obvious to
    synchronize on the Calendar class.

    But in general (for instance methods) I would make the opposite
    assumption: unless the doc states that it is thread safe, then
    I will assume that it is not.

    Arne
     
    Arne Vajhøj, Mar 7, 2010
    #3
  4. endymion

    markspace Guest

    Peter Duniho wrote:
    > markspace wrote:
    >> endymion wrote:
    >>
    >>> So the question is: Is Calendar.getInstance() thread safe?

    >>
    >>
    >> I think you have to assume all methods are thread safe unless there is
    >> documentation to the contrary. How could you call any method reliably
    >> unless it was deemed to be safe to do so?

    >
    > By synchronizing when you need to call them simultaneously from multiple
    > threads.
    >



    Synchronizing on what? Synchronization requires a shared object to be
    effective. If you synchronize on ObjectA, and the body of some method
    you call synchronizes on ObjectB, then nothing has been done and no
    synchronization occurs.

    If the method does not document what object you need to synchronize on,
    then you can't do anything with it.

    I think you know this, and maybe we are talking at cross purposes. What
    I mean by "thread safe" here is that a method can be called safely by a
    single thread. If you can't do that, then you can't make the call. The
    OP doesn't seem to be implying anything different. He says he has
    multiple threads, but doesn't provide any interaction between them other
    than making one method call. Well, yes, that has to be safe, or no
    thread at all could call the method. If it were not safe, like Java's
    Swing methods, then it should be documented.


    > I doubt the Calendar class is thread-safe, except possibly static
    > methods like getInstance(). Typically, classes are NOT thread-safe
    > unless documented otherwise.



    By a single thread, sure, they must be. Objects aren't thread safe by
    default. I see what you are saying, but sometimes I think people get
    confused as to what thread safety really means, or does.

    There's an implicit guarantee in all methods that they are safe to call
    from a single thread. You have to have that or the method is just
    broken. And that's all the OP has shown us, is a single method call by
    a single thread. That much is always "thread safe."
     
    markspace, Mar 7, 2010
    #4
  5. endymion

    Arne Vajhøj Guest

    On 07-03-2010 12:07, markspace wrote:
    > Peter Duniho wrote:
    >> I doubt the Calendar class is thread-safe, except possibly static
    >> methods like getInstance(). Typically, classes are NOT thread-safe
    >> unless documented otherwise.

    >
    > By a single thread, sure, they must be.


    What is thread safe by single thread?

    I agree with:

    http://en.wikipedia.org/wiki/Thread_safe

    "A piece of code is thread-safe if it functions correctly during
    simultaneous execution by multiple threads."

    Thread safety as a concept relates to multiple threads.

    Arne
     
    Arne Vajhøj, Mar 7, 2010
    #5
  6. endymion wrote:
    > Hi,
    >
    > In a multi-threaded application, I encountered problems with dates
    > being "reset" to 1970, or being negative when converted into ms since
    > 1970.
    >
    > I use Calendar to do operations on dates, and as I see no obvious bug
    > in the code, and as the problem occurs randomly and after a certain
    > time, I was wondering if that was a multi-threading issue.
    >
    > So the question is: Is Calendar.getInstance() thread safe?


    It would be odd as hell for a static factory method not to be thread-safe.
    But since this isn't documented anywhere, let's have a look at the source
    code (for 1.5.0_16-b02):

    public static Calendar getInstance()
    {
    Calendar cal = createCalendar(TimeZone.getDefaultRef(),
    Locale.getDefault());
    cal.sharedZone = true;
    return cal;
    }

    private static Calendar createCalendar(TimeZone zone,
    Locale aLocale)
    {
    // If the specified locale is a Thai locale, returns a
    BuddhistCalendar
    // instance.
    if ("th".equals(aLocale.getLanguage())
    && ("TH".equals(aLocale.getCountry()))) {
    return new sun.util.BuddhistCalendar(zone, aLocale);
    }

    // else create the default calendar
    return new GregorianCalendar(zone, aLocale);
    }

    Not much doubt that it always returns a newly constructed one. If the
    version you're using might return the same Calendar twice, it has a pretty
    significant bug in it.
     
    Mike Schilling, Mar 7, 2010
    #6
  7. endymion

    markspace Guest

    Arne Vajhøj wrote:
    > On 07-03-2010 12:07, markspace wrote:
    >> Peter Duniho wrote:
    >>> I doubt the Calendar class is thread-safe, except possibly static
    >>> methods like getInstance(). Typically, classes are NOT thread-safe
    >>> unless documented otherwise.

    >>
    >> By a single thread, sure, they must be.

    >
    > What is thread safe by single thread?



    I'll give you a counter example: Most Swing methods are NOT thread safe
    for a single thread to call, since they interact with the EDT and will
    not synchronize properly between the caller and the EDT.

    Let me try to explain my idea a bit more:

    Given some method a(), if the results of a() are visible to the calling
    thread (all object properly constructed, any threads started by the
    method synchronize properly with objects they interact with, etc.) then
    a() is safe for a single thread to call.

    If the results are not visible (objects are NOT properly created) then
    that method isn't safe. Again, using Swing:

    public void createAndShowGui() {
    JFrame frame = new JFrame( "Not safe." );
    frame.add( new Label( "This isn't safe" ) );
    frame.pack();
    frame.setVisible( true );
    }

    This method is not safe to call, since it doesn't synchronize with the
    EDT, and the objects aren't created in a thread safe manner. It's not
    safe for even one thread to call without special consideration (being
    called on the EDT).

    Another example might be a method which uses a persistence layer to
    makes database calls, perhaps on a separate thread. That method is
    responsible for making sure all objects created or interacted with are
    visible to the calling thread, or else document what the calling thread
    has to do to make those objects visible.

    Brian Goetz talks about this in Java Concurrency in Practice, that
    single-thread safety is the default. Anything different must be documented.
     
    markspace, Mar 7, 2010
    #7
  8. endymion

    Arne Vajhøj Guest

    On 07-03-2010 12:52, markspace wrote:
    > Arne Vajhøj wrote:
    >> On 07-03-2010 12:07, markspace wrote:
    >>> Peter Duniho wrote:
    >>>> I doubt the Calendar class is thread-safe, except possibly static
    >>>> methods like getInstance(). Typically, classes are NOT thread-safe
    >>>> unless documented otherwise.
    >>>
    >>> By a single thread, sure, they must be.

    >>
    >> What is thread safe by single thread?

    >
    > I'll give you a counter example: Most Swing methods are NOT thread safe
    > for a single thread to call, since they interact with the EDT and will
    > not synchronize properly between the caller and the EDT.


    my thread + EDT = single thread

    ????

    > Let me try to explain my idea a bit more:
    >
    > Given some method a(), if the results of a() are visible to the calling
    > thread (all object properly constructed, any threads started by the
    > method synchronize properly with objects they interact with, etc.) then
    > a() is safe for a single thread to call.


    If the code in a() is thread safe then a() is thread safe. That
    is hardly surprising.

    > Brian Goetz talks about this in Java Concurrency in Practice, that
    > single-thread safety is the default. Anything different must be documented.


    It is reasonable to expect that the library does not start any threads
    working on the objects unless the documentation state so.

    But I still don't see much point in considering a single thread
    scenario for thread safe.

    Arne
     
    Arne Vajhøj, Mar 7, 2010
    #8
  9. Well, to the question: "is getInstance thread safe?", the answer is yes and
    I thank you all for your help.

    I guess I have to conclude that the odd behaviour I get is related to my own
    code rather than Java's Calendar class.
    I would have prefered the mistake to be in Java standard API's, but... ;-)

    So, I'll try to have a SSCCE, and that's what I should have done at the
    beginning.

    Thanks again for your answers and the interesting discussion on thread
    safety.

    Christophe B.

    Peter Duniho wrote:

    > markspace wrote:
    >> endymion wrote:
    >>
    >>> So the question is: Is Calendar.getInstance() thread safe?

    >>
    >>
    >> I think you have to assume all methods are thread safe unless there is
    >> documentation to the contrary. How could you call any method reliably
    >> unless it was deemed to be safe to do so?

    >
    > By synchronizing when you need to call them simultaneously from multiple
    > threads.
    >
    > I doubt the Calendar class is thread-safe, except possibly static
    > methods like getInstance(). Typically, classes are NOT thread-safe
    > unless documented otherwise.
    >
    > That said, I agree with the rest of your comments. The Calendar class
    > is mutable, so it wouldn't make sense if the "getInstance()" overloads
    > didn't create new instances each time they are called. So while not
    > explicitly stated, simply by virtue of how they work, those methods
    > should be thread-safe without any explicit implementation to make them so.
    >
    > And indeed, if you look at the source code for the java.util.Calendar
    > class, the getInstance() methods call a private static method
    > createCalendar(), the essence of which is simply to use "new" to create
    > a new instance. And "new" is definitely thread-safe.
    >
    > So if there's a thread-safety bug, it's probably in the OP's code, which
    > of course without a concise-but-complete code example (SSCCE) we would
    > not be able to point out.
    >
    > Pete
     
    Christophe B., Mar 7, 2010
    #9
  10. endymion

    markspace Guest

    Peter Duniho wrote:
    > markspace wrote:
    >> [...]
    >> Brian Goetz talks about this in Java Concurrency in Practice, that
    >> single-thread safety is the default. Anything different must be
    >> documented.

    >
    > Surely by that he specifically means that the default is for a class to
    > NOT be thread-safe.



    No he meant what I wrote. His exact discussion concerned the database
    driver object, which is well known to be multi-threaded, but doesn't
    document its thread safety. In fact, there were a few buggy
    implementations which weren't safe for a single thread to execute.
    Which was his whole point: in the absence of documentation, you have to
    assume that method invocation is safe for a single thread. That's for
    the caller and the implementer both.

    I'll look up the chapter if you're interested in a reference, but it's
    pretty easy to find too if you have a copy.

    Second point: I said "method" (and so did the OP), you said class.
    There's a difference. I'm only talking about the invocation of a single
    method call by a single thread here.

    >
    > As Arne says, the idea of "thread safe" pertains
    > only to multi-thread scenarios.



    Which is possible to have multiple threads even if you have only one
    thread yourself.


    > ALL code is trivially thread safe for
    > single-thread scenarios, and calling code "thread safe" but qualified to
    > only the single-thread scenario makes no sense.



    'cept for that Swing method I showed, and that buggy driver
    implementation I mentioned, and ....
     
    markspace, Mar 7, 2010
    #10
  11. endymion

    Roedy Green Guest

    On Sun, 07 Mar 2010 16:59:57 +0100, endymion <> wrote,
    quoted or indirectly quoted someone who said :

    >
    >In a multi-threaded application, I encountered problems with dates being
    >"reset" to 1970, or being negative when converted into ms since 1970.


    I have got in trouble with SimpleDateFormat not being thread safe.
    Don't make them static unless you have but a single thread.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time.
    ~ Tom Cargill
     
    Roedy Green, Mar 8, 2010
    #11
  12. Roedy Green wrote:

    > I have got in trouble with SimpleDateFormat not being thread safe.


    How possibly _could_ a SimpleDateFormat be thread safe?


    Regards, Lothar
    --
    Lothar Kimmeringer E-Mail:
    PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

    Always remember: The answer is forty-two, there can only be wrong
    questions!
     
    Lothar Kimmeringer, Mar 9, 2010
    #12
  13. endymion

    Mayeul Guest

    Lothar Kimmeringer wrote:
    > Roedy Green wrote:
    >
    >> I have got in trouble with SimpleDateFormat not being thread safe.

    >
    > How possibly _could_ a SimpleDateFormat be thread safe?


    ?

    What do you mean ? It looks to me if SimpleDateFormat had been designed
    immutable, it would make sense to have it thread-safe, as other
    languages or libraries have it.

    Actually, even though its mutable, I would have expected it to be
    thread-safe as long as you don't mutate it anymore. Thankfully the
    JavaDoc is clear that it's not. Oh well.

    --
    Mayeul
     
    Mayeul, Mar 9, 2010
    #13
  14. Mayeul wrote:

    > Lothar Kimmeringer wrote:
    >> Roedy Green wrote:
    >>
    >>> I have got in trouble with SimpleDateFormat not being thread safe.

    >>
    >> How possibly _could_ a SimpleDateFormat be thread safe?

    >
    > ?
    >
    > What do you mean ? It looks to me if SimpleDateFormat had been designed
    > immutable, it would make sense to have it thread-safe, as other
    > languages or libraries have it.


    I mean, how can you expect it to be thread safe if the Javadoc
    clearly states

    | 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.

    > Actually, even though its mutable, I would have expected it to be
    > thread-safe as long as you don't mutate it anymore. Thankfully the
    > JavaDoc is clear that it's not. Oh well.


    Ah, you read it (now) ;-)


    Regards, Lothar
    --
    Lothar Kimmeringer E-Mail:
    PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

    Always remember: The answer is forty-two, there can only be wrong
    questions!
     
    Lothar Kimmeringer, Mar 9, 2010
    #14
  15. endymion

    Roedy Green Guest

    On Tue, 9 Mar 2010 16:36:35 +0100, Lothar Kimmeringer
    <> wrote, quoted or indirectly quoted someone
    who said :

    >I mean, how can you expect it to be thread safe if the Javadoc
    >clearly states


    It was quite some time ago I got in trouble. I suppose I thought of a
    SimpleDateFormat as sort of static final constant, like the string
    that describes a Regex.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time.
    ~ Tom Cargill
     
    Roedy Green, Mar 10, 2010
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Eric
    Replies:
    6
    Views:
    8,813
  2. yzzzzz
    Replies:
    14
    Views:
    44,441
    Tor Iver Wilhelmsen
    Feb 10, 2005
  3. jlowery05
    Replies:
    51
    Views:
    1,870
    Chris Uppal
    Mar 15, 2006
  4. Gabriel Rossetti
    Replies:
    0
    Views:
    1,376
    Gabriel Rossetti
    Aug 29, 2008
  5. John Nagle
    Replies:
    5
    Views:
    496
    John Nagle
    Mar 12, 2012
Loading...

Share This Page