java.util.Calendar线程是否安全?
我一直在假设Date
和Calendar
都不是线程安全的,但在最近的讨论中,一位同事告诉我Calendar
是线程安全的。
所以,我做了一些研究,没有提出任何建议。 有很多人认为它是线程安全的,很多人认为它不是线程安全的。 而且,最重要的是,文档不会以任何方式说出任何内容,不是针对Calendar
,甚至也不是针对Date
。
那么,这是什么?
这是Java 7中Calendar和GregorianCalendar源代码的链接
如果您阅读代码,您将看到没有任何实例方法同步,并且所有实例字段都不是volatile
。 您还将看到即使是字段get
方法也可能导致Calendar实例发生变异。 并且由于没有执行同步,不同的线程可能会在这样的变异操作之后看到Calendar对象的字段的陈旧版本。
对于记录,字段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
也不是因为它inheritance了非线程安全的字段和方法。
但是,不要只听我的话。 自己分析源代码。
而且,最重要的是,文档不会以任何方式说出任何内容,不是针对日历,甚至也不是针对日期。
如果javadocs没有指定类的线程安全性,那么您应该假设它不是线程安全的。
Oracle的文档没有提及线程安全性: http : //docs.oracle.com/javase/7/docs/api/java/util/Calendar.html 。
OpenJDK源代码(build 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
。
–我没有在primefaces语句中找到任何synchronized
关键字,也没有在Calendar类和子类中找到volatile
字段。