問題描述
我一直在假設 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 線程是否安全?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!