我希望我的应用程序只有一个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();
...
谢谢!
答案 0 :(得分:7)
我看了一下它的源代码并得出结论它不是。
查看JodaTime timezone课程。它在javadoc中说它是线程安全且不可变的。
答案 1 :(得分:6)
不是。
你不需要它。您的代码将其用作:
final TimeZone tz = TimeZone.getTimeZone("GMT");
......
// thread 1 SimpleDateFormat instance
sdf.setTimeZone(tz);
// thread 2 SimpleDateFormat instance
sdf.setTimeZone(tz);
你有两个线程使用相同的时区,但由于你没有修改它,你不需要它是线程安全的。
你可以修改的唯一内容是ID,但即便如此,你也可以,因为其他属性是只读的
唯一可以解决问题的方法是更改ID并自行缓存时区,如果你总是从TimeZone.getTimeZone()
获得它也是安全的,因为该方法 线程安全。
答案 2 :(得分:2)
没有明确的文档表明TimeZone是线程安全的,所以最安全的路由是假设它不是线程安全的。
TimeZone类有两个实例变更器,与ID及其GMT偏移有关。常识会说Calendar.getInstance和SimpleDateFormat没有业务修改TimeZone对象状态(在第一种情况下,它被用作查找键,在第二种情况下,用作格式化上下文)。
常识或确定性 - 您的选择。
答案 3 :(得分:1)
您没有修改TimeZone,因此无论TimeZone的底层实现是否是线程安全的(除了静态方法,如(getTimeZone / getDefault / setDefault)),您的代码应该是线程安全的。
答案 4 :(得分:0)
此出现即可。如果你依赖于TimeZone.getDefault()那将是一个不同的故事。由于另一个线程可能正在调用TimeZone.setDefault()。