Является ли Java TimeZone поточно-ориентированным? - PullRequest
16 голосов
/ 13 ноября 2009

Я хотел, чтобы в моем приложении был только один объект TimeZone, который будет одновременно использоваться многими объектами SimpleDateFormat и Calendar из других мест. Это чтобы избежать необходимости всегда делать TimeZone.getTimeZone(ID).

Я знаю, что классы SimpleDateFormat и Calendar не являются поточно-ориентированными, поэтому я настраиваю один поток, чтобы всегда создавать их новые экземпляры. Но как насчет TimeZone? Мне не ясно, могу ли я сделать следующее безопасно:

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();
...

Спасибо!

Ответы [ 5 ]

7 голосов
/ 13 ноября 2009

Я однажды посмотрел на исходный код и пришел к выводу, что это не так.

Посмотрите на часовой пояс JodaTime класс. В javadoc написано, что он потокобезопасен и неизменен.

6 голосов
/ 13 ноября 2009

Это не так.

И тебе это не нужно. Ваш код использует его как:

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

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

У вас есть два потока, использующих один и тот же часовой пояс, но, поскольку вы не изменяете его, вам не нужно, чтобы он был безопасным для потоков.

Единственное, что вы можете изменить, это идентификатор, но даже тогда вы в порядке, а остальные атрибуты доступны только для чтения.

Единственный способ попасть в неприятности - это изменить идентификатор и кэшировать себя в часовом поясе, если вы всегда получаете его из TimeZone.getTimeZone(), вы тоже в безопасности, потому что этот метод является поточно-ориентированным .

2 голосов
/ 13 ноября 2009

Нет явной документации, в которой говорится, что TimeZone является поточно-ориентированным, поэтому самый безопасный маршрут - предполагать, что он не является поточно-безопасным.

Класс TimeZone имеет два мутатора экземпляра, относящиеся к идентификатору и его смещению по Гринвичу. Здравый смысл сказал бы, что Calendar.getInstance и SimpleDateFormat не имеют никаких бизнес-модификаций, изменяющих состояние объекта TimeZone (в первом случае он используется как ключ поиска, а во втором - как контекст форматирования).

Здравый смысл или уверенность - ваш выбор.

1 голос
/ 13 ноября 2009

Вы не изменяете свою TimeZone, поэтому ваш код должен быть потокобезопасным независимо от того, является ли базовая реализация TimeZone поточно-безопасной (за исключением статических методов, например (getTimeZone / getDefault / setDefault).

0 голосов
/ 13 ноября 2009

Это кажется в порядке. Если бы вы полагались на TimeZone.getDefault (), это была бы другая история. Поскольку другой поток потенциально может вызывать TimeZone.setDefault ().

...