我一直在假设没有下工作的Date
,也没有Calendar
是线程安全的,但是,最近的一次讨论中,一位同事告诉我的Calendar
是线程安全的。
所以,我做了一些研究,并与一无所获。 有很多人声称它是线程安全的,并且很多人争论它不是线程安全的。 而且,最糟糕的是,文件没有说什么这种或那种方式,而不是Calendar
,甚至也没有为Date
。
所以,这是什么呢?
我一直在假设没有下工作的Date
,也没有Calendar
是线程安全的,但是,最近的一次讨论中,一位同事告诉我的Calendar
是线程安全的。
所以,我做了一些研究,并与一无所获。 有很多人声称它是线程安全的,并且很多人争论它不是线程安全的。 而且,最糟糕的是,文件没有说什么这种或那种方式,而不是Calendar
,甚至也没有为Date
。
所以,这是什么呢?
下面是源代码的链接日历和GregorianCalendar的 Java 7中
如果你读的代码,你会看到,没有一个实例方法是同步的,并没有实例字段是volatile
。 你也可以看到,即使是场get
方法可能会导致一个日历实例发生变异。 而且,由于没有进行同步,不同的线程可能会看到下面这样的变异操作的日历对象的字段的陈旧版本。
根据记录,在该领域的突变作用get方法调用此方法期间发生在/:
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
是不是可能是因为它继承了非线程安全的领域和方法。
但是,不要只相信我的话。 做你自己的源代码的分析。
而且,最糟糕的是,文件没有说什么这种或那种方式,而不是日历,甚至也没有为日期。
如果javadocs中没有指定一个类的线程安全的,那么你就应该认为它是不是线程安全的。
从Oracle文档只字未提线程安全: http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html 。
OpenJDK的源代码(建B147)实现java.util.Calendar
在非线程安全的方式,例如:
public void setTimeInMillis(long millis) {
// skipped
time = millis;
isTimeSet = true;
areFieldsSet = false;
computeFields();
areAllFieldsSet = areFieldsSet = true;
}
我认为它是安全的假设类不是线程安全的。
-我不是从那里你的朋友得到的信息肯定,但在简单和直接来说的, Calendar class is
不是 Thread safe
。
-我没有发现任何synchronized
在原子陈述,也不关键字volatile
在Calendar类,也不在其子类领域。