【发布时间】:2017-10-08 13:29:46
【问题描述】:
Java Concurrency in Practice 说,您可以安全地发布一个有效的不可变对象(例如,您构造并且不再更改的 Date 对象),方法是将其粘贴到如下所示的同步集合中(摘自本书,第 53 页):
public Map<String, Date> lastLogin =
Collections.synchronizedMap(new HashMap<String, Date>())
我了解,任何放入此映射的 Date 对象在放入此同步映射后都将是可见的(至少在其初始但完全构造的状态下),但只有在其他线程可以获得对此 Map 对象的引用时。
由于引用字段 lastLogin 没有保证可见性的字段属性(final、volatile、guarded 或由静态初始化程序初始化),我认为地图本身可能不会以完全构造的状态显示到其他线程,因此本末倒置。还是我错过了什么?
【问题讨论】:
-
顺便说一句... (a) java.time 类,例如
Instant、LocalDate和ZonedDateTime确实是不可变的和线程安全的。所以无需构建自己的日期类。 ☺ (b) 避免使用麻烦的遗留类,如java.util.Date和Calendar,因为它们不是线程安全的并且还有许多其他问题。 ☹ -
我认为它可以工作,因为同步的集合在某些时候会调用同步,这总是使完整状态对其他线程可见。
-
假设 lastLogin 本身是安全发布的;他想要得到的是,一旦你有了对地图的参考,你就可以用它来安全地发布其他参考。
标签: java multithreading