是java.util.Calendar中的线程安全与否?(Is java.util.Calendar

2019-06-27 09:18发布

我一直在假设没有下工作的Date ,也没有Calendar是线程安全的,但是,最近的一次讨论中,一位同事告诉我的Calendar是线程安全的。

所以,我做了一些研究,并与一无所获。 有很多人声称它是线程安全的,并且很多人争论它不是线程安全的。 而且,最糟糕的是,文件没有说什么这种或那种方式,而不是Calendar ,甚至也没有为Date

所以,这是什么呢?

Answer 1:

下面是源代码的链接日历和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中没有指定一个类的线程安全的,那么你就应该认为它是不是线程安全的。



Answer 2:

从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;
}

我认为它是安全的假设类不是线程安全的。



Answer 3:

-我不是从那里你的朋友得到的信息肯定,但在简单和直接来说的, Calendar class is 不是 Thread safe

-我没有发现任何synchronized在原子陈述,也不关键字volatile在Calendar类,也不在其子类领域。



文章来源: Is java.util.Calendar thread safe or not?
标签: java calendar