gpt4 book ai didi

java - Java Concurrency in Practice 中的安全发布示例

转载 作者:搜寻专家 更新时间:2023-10-31 20:00:07 24 4
gpt4 key购买 nike

Java Concurrency in Practice 说你可以安全地发布一个有效的不可变对象(immutable对象)(比如,一个你构造的 Date 对象,并且永远不会再改变),方法是将它粘贴到同步集合中,如下所示(摘自本书,第 53 页):

public Map<String, Date> lastLogin =
Collections.synchronizedMap(new HashMap<String, Date>())

据我了解,一旦放入此同步映射中,放入此映射中的任何 Date 对象都将可见(至少在其初始但完全构建的状态下),但只有在其他线程可以获得对此 Map 对象的引用时。

由于引用字段 lastLogin 没有保证可见性的字段属性(final、volatile、guarded 或由静态初始化程序初始化),我认为 map 本身可能不会以完全构造的状态显示到其他线程,因此本末倒置。还是我遗漏了什么?

最佳答案

您的怀疑只对了一半,因为 lastLogin 的值不能保证对其他线程可见。因为 lastLogin 不是 volatilefinal,所以另一个线程可能会将其读取为 null

但是,您不必担心其他线程会看到 map 的不完整版本。 Collections.synchronizedMap(...) 返回 a private class 的一个实例带有 final 字段。 JLS section 17.5说:

The usage model for final fields is a simple one: Set the final fields for an object in that object's constructor; and do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished. If this is followed, then when the object is seen by another thread, that thread will always see the correctly constructed version of that object's final fields.

SynchronizedMap 遵循这些规则,因此另一个读取 lastLogin 的线程将读取 null 或对完整构造映射的引用,而不是引用 map 的不完整或不安全版本。

关于java - Java Concurrency in Practice 中的安全发布示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43883329/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com