问题描述
我一直在假设 Date
和 Calendar
都不是线程安全的,但是,在最近的一次讨论中,一位同事告诉我 日历
是线程安全的.
I've been working under the assumption that neither Date
nor Calendar
are thread-safe, but, during a recent discussion, a co-worker told me Calendar
was thread-safe.
所以,我做了一些研究,但一无所获.有很多人认为它是线程安全的,也有很多人认为它不是线程安全的.而且,最重要的是,文档并没有以任何方式说明任何事情,对于 Calendar
,甚至对于 Date
也没有.
So, I did some research, and came up with nothing. There are plenty people arguing it's thread-safe, and plenty people arguing it's not thread-safe. And, to top it off, the documentation doesn't say anything one way or another, not for Calendar
, nor even for Date
.
那么,它是什么?
推荐答案
这里是日历 和 GregorianCalendar
如果您阅读代码,您会发现没有一个实例方法是同步的,并且没有一个实例字段是 volatile
.您还将看到,即使是字段 get
方法也可能导致 Calendar 实例发生变异.而且由于没有执行同步,不同的线程可能会在这样的变异操作之后看到日历对象字段的陈旧版本.
If you read the code you will see that none of the instance methods are synchronized, and none of the instance fields are volatile
. You will also see that even the field get
methods can cause a Calendar instance to mutate. And since there is no synchronization performed, different threads may see stale versions of a Calendar object's fields following such a mutating operation.
作为记录,字段 get 方法中的突变操作发生在/调用此方法期间:
For the record, the mutation action in the field get methods happens in / during a call to this method:
1555 protected void complete()
1556 {
1557 if (!isTimeSet)
1558 updateTime();
1559 if (!areFieldsSet || !areAllFieldsSet) {
1560 computeFields(); // fills in unset fields
1561 areAllFieldsSet = areFieldsSet = true;
1562 }
1563 }
简而言之,Calendar
类不是线程安全的,GregorianCalendar
也不是,因为它继承了非线程安全的字段和方法.
In short, the Calendar
class is not thread-safe, and GregorianCalendar
isn't either because it inherits the non-thread-safe fields and methods.
但不要只相信我的话.自己分析源代码.
But don't just take my word for it. Do your own analysis of the source code.
而且,最重要的是,文档并没有以任何方式说明任何事情,对于日历,甚至对于日期都没有.
And, to top it off, the documentation doesn't say anything one way or another, not for Calendar, nor even for Date.
如果 javadocs 没有指定类的线程安全性,那么您应该假设它不是线程安全的.(特别是如果类是可变的设计.)
If the javadocs don't specify the thread-safety of a class, then you should assume that it is not thread-safe. (Especially if the class is mutable by design.)
这篇关于java.util.Calendar 线程是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!