Является ли Java TimeZone потокобезопасным?
Я хотел, чтобы мое приложение просто имело один объект 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();
...
Спасибо!
Ответы
Ответ 1
Это не так.
И вам это не нужно. Вы используете его как:
final TimeZone tz = TimeZone.getTimeZone("GMT");
......
// thread 1 SimpleDateFormat instance
sdf.setTimeZone(tz);
// thread 2 SimpleDateFormat instance
sdf.setTimeZone(tz);
У вас есть два потока, использующих один и тот же часовой пояс, но поскольку вы не изменяете его, вам не нужно быть потокобезопасным.
Единственное, что вы можете изменить, это ID, но даже тогда вы в порядке, поскольку остальные атрибуты доступны только для чтения
Единственный способ, с помощью которого вы можете столкнуться, - это изменить идентификатор и кешировать себя часовым поясом, если вы всегда получаете его из TimeZone.getTimeZone()
, вы тоже в безопасности, потому что этот метод - это поток сейф.
Ответ 2
Я посмотрел один раз на исходный код и пришел к выводу, что это не так.
Посмотрите класс JodaTime часовой пояс. В javadoc говорится, что он потокобезопасен и неизменен.
Ответ 3
Нет явной документации, в которой указано, что TimeZone является потокобезопасным, поэтому самый безопасный маршрут предполагает, что он не является потокобезопасным.
Класс TimeZone имеет два экземпляра-мутатора, относящихся к ID и его смещению по GMT. Здравый смысл скажет, что Calendar.getInstance и SimpleDateFormat не имеют бизнес, изменяющий состояние объекта TimeZone (в первом случае он используется как ключевой ключ, а во втором - как формат форматирования).
Здравый смысл или определенность - ваш выбор.
Ответ 4
Вы не изменяете свой TimeZone, поэтому ваш код должен быть потокобезопасным независимо от того, является ли базовая реализация TimeZone потокобезопасной (за исключением статических методов, например (getTimeZone/getDefault/setDefault).
Ответ 5
Кажется, что все в порядке. Если вы полагаетесь на TimeZone.getDefault(), это будет другая история. Поскольку другой поток потенциально может быть вызван TimeZone.setDefault().