开发者

How to make a static Calendar thread safe

I'd like to use a Calendar for some static methods and use a static field:

private static Calendar calenda开发者_如何学编程r = Calendar.getInstance();

Now I read java.util.Calendar isn't thread safe. How can I make this thread safe (it should be static)?


You can't make something thread-safe if it isn't. In the case of Calendar, even reading data from it isn't thread-safe, as it can update internal data structures.

If at all possible, I'd suggest using Joda Time instead:

  • Most of the types are immutable
  • The immutable types are thread-safe
  • It's a generally much better API anyway

If you absolutely have to use a Calendar, you could create a locking object and put all the access through a lock. For example:

private static final Calendar calendar = Calendar.getInstance();
private static final Object calendarLock = new Object();

public static int getYear()
{
    synchronized(calendarLock)
    {
        return calendar.get(Calendar.YEAR);
    }
}

// Ditto for other methods

It's pretty nasty though. You could have just one synchronized method which created a clone of the original calendar each time it was needed, of course... it's possible that by calling computeFields or computeTime you could make subsequent read-operations thread-safe, of course, but personally I'd be loathe to try it.


Calendar is thread safe provided you don't change it. The usage in your example is fine.

It is worth noting that Calendar is not an efficient class and you should only use it for complex operations (like finding the next month/year) IMHO: If you do use it for complex operations, use local variables only.

If all you want it a snapshot of the time a faster way is to use currentTimeMillis which does even create an object. You can make the field volatile if you want to make it thread safe.

private static long now = System.currentTimeMillis();

The usage is a bit suspect. Why would you get the current time and store it globally like this. It reminds me of the old joke.

- Do you have the time?
- Yes, I have it written down somewhere.


You cannot. Yes, you could synchronize on it, but it still has mutable state fields. You'll have to create your own Calendar object.

If possible, use something lightweight, like a long measuring the times in milliseconds, and only convert to a Calendar when you NEED to.


Create a Calendar as a local variable in the method. If you need the same calendar across methods, you may be using statics where a (singleton or quasi-singleton) object would be more appropriate.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜