views:

420

answers:

5

I wanted my application to just have one TimeZone object which will be used by many SimpleDateFormat and Calendar objects from the other places concurrently. This is to avoid having to always do TimeZone.getTimeZone(ID).

I know SimpleDateFormat and Calendar classes are not thread safe, which is why I configure one thread to always create new instances of them. But what about TimeZone? It is not clear to me whether I can do the following safely:

final TimeZone tz = TimeZone.getTimeZone("GMT");
...
//Thread 1.
Thread t1 = new Thread(Runnable(){
    public void run()
    {
        Calendar cal = Calendar.getInstance(tz);
        ...
        SimpleDateFormat sdf = new SimpleDateFormat();
        sdf.setTimeZone(tz);
        ...
    }
});
t1.start();
...
//Thread 2.
Thread t2 = new Thread(Runnable(){
    public void run()
    {
        Calendar cal = Calendar.getInstance(tz);
        ...
        SimpleDateFormat sdf = new SimpleDateFormat();
        sdf.setTimeZone(tz);
        ...
    }
});
t2.start();
...

Thanks!

+3  A: 

I looked once at the source code for it and came to a conclusion that it was not.

Look at JodaTime timezone class. It says in javadoc that it's thread-safe and immutable.

Alexander Pogrebnyak
+1: JodaTime is the way to do date/time in Java.
BalusC
A: 

You are not modifying your TimeZone, so your code should be thread safe regardless of whether the underlying implementation of TimeZone is thread safe (with the exception of static methods, like (getTimeZone/getDefault/setDefault).

Keith Randall
Actually, TimeZone.getDefault() and TimeZone.setDefault() get and set a thread-local default. Take a look at the source code!
Stephen C
No :) its not, http://stackoverflow.com/questions/2176784/timezone-setdefault-changes-in-jdk6
Tom
A: 

This appears to be OK. If you were relying on TimeZone.getDefault() that would be a different story. As another thread could potentially be calling TimeZone.setDefault().

Chris Gummer
Actually, that **would** be safe. `TimeZone.getDefault()` and `TimeZone.setDefault()` get and set a thread-local default. Take a look at the source code!
Stephen C
Will do - thanks!
Chris Gummer
@StephenC - no its not safe. Please look athttp://stackoverflow.com/questions/2176784/timezone-setdefault-changes-in-jdk6
Tom
A: 

There is no explicit documentation that states TimeZone is thread-safe, so the safest route is assume that it isn't thread safe.

The TimeZone class has two instance mutators, relating to ID and its GMT offset. Common sense would say that Calendar.getInstance and SimpleDateFormat have no business modifying TimeZone object state (in the first case, it's being used as a look-up key, and in the second, as formatting context).

Common sense or certainty - your choice.

Noel Ang
A: 

It is not.

And you don't need it. You code uses it as:

final TimeZone tz = TimeZone.getTimeZone("GMT");
 ......
// thread 1 SimpleDateFormat instance
sdf.setTimeZone(tz);

// thread 2 SimpleDateFormat instance
sdf.setTimeZone(tz);

You have two threads using the same time zone, but since you are not modifying it you don't need it to be thread safe.

The only thing that you can modify is the ID, but even then you're ok, for the rest of the attributes are read-only

The only way you can get into trouble is by changing the id and caching your self the timezone, if you get it always from the TimeZone.getTimeZone() you are safe too, because that method is thread safe.

OscarRyz