我正在使用 joda,因为它在多线程方面享有盛誉。使多线程日期处理高效,例如通过使所有 Date/Time/DateTime 对象不可变,还有很长的路要走。
但在这种情况下,我不确定 Joda 是否真的在做正确的事情。可能确实如此,但我很想看到解释。
当调用 DateTime 的 toString() 时,Joda 会执行以下操作:
/* org.joda.time.base.AbstractInstant */
public String toString() {
return ISODateTimeFormat.dateTime().print(this);
}
所有格式化程序都是线程安全的(它们也是不可变的),但是格式化程序工厂是什么:
private static DateTimeFormatter dt;
/* org.joda.time.format.ISODateTimeFormat */
public static DateTimeFormatter dateTime() {
if (dt == null) {
dt = new DateTimeFormatterBuilder()
.append(date())
.append(tTime())
.toFormatter();
}
return dt;
}
这是单线程应用程序中的常见模式,但众所周知,它在多线程环境中容易出错。
我看到以下危险:
- 空值检查期间的竞争条件-> 最坏情况:创建了两个对象。
没问题,因为这只是一个辅助对象(与正常的单例模式情况不同),一个保存在 dt 中,另一个丢失,迟早会被垃圾收集。
- 在对象完成初始化之前,静态变量可能指向部分构造的对象
(在说我疯之前,请阅读这篇维基百科文章中的类似情况。)
那么 Joda 如何确保没有部分创建的格式化程序被发布到这个静态变量中呢?
感谢您的解释!
雷托