Java 在ConcurrentHashMap中存储复杂对象

Java 在ConcurrentHashMap中存储复杂对象,java,multithreading,concurrency,Java,Multithreading,Concurrency,根据实践中的Java并发性,以下代码可能抛出断言错误: 如果发布线程以外的线程要调用 assertSanity,它可能会抛出断言错误 public class Holder { private int n; public Holder(int n) { this.n = n; } public void assertSanity() { if (n != n) throw new AssertionError("This statement is false."); } } // Unsa

根据实践中的Java并发性,以下代码可能抛出断言错误:

如果发布线程以外的线程要调用 assertSanity,它可能会抛出断言错误

  public class Holder {
private int n;
public Holder(int n) { this.n = n; }
public void assertSanity() {
if (n != n)
throw new AssertionError("This statement is false.");
}
}

// Unsafe publication
public Holder holder;
public void initialize() {
holder = new Holder(42);
}
问题是:如果我保存一个引用ConcurrentHashMap中其他对象的对象,在多线程环境中,是否有可能由于与上述示例相同的原因,该对象图上的某些更新不同步


虽然对象图中的根节点将始终在映射中为所有线程更新,但如果这些对象不是最终的或不稳定的,那么根节点中被称为字段的其他对象又如何呢?

ConcurrentHashMap保证保存在ConcurrentHashMap中的所有引用操作(链接到对象)都是线程安全的,当然,ConcurrentHashMap不能保证线程安全,因为引用(链接)存储在ConcurrentHashMap中

回答我自己的问题,我应该在提问之前阅读完整的一章。这是本章后面部分所说的:

可变对象:如果一个对象在构建后可能会被修改,则安全 发布仅确保发布状态的可见性。 同步不仅必须用于发布可变对象,还必须用于 此外,每次访问对象时都要确保对象的可见性 随后的修改。为了安全地共享可变对象,它们必须 安全发布,线程安全或由锁保护


因此,在多线程环境中使用CHM或任何线程安全集合是不安全的,除非您同步对CHM中可变对象的更改,或者这些对象是不可变的。

您的意思是,对象图中的更改将不同步,如果在不同的线程中访问相同的CHM?如果我们谈论的是对象图,所有节点的链接都只保存在CHM中,是的,它是同步的。我仍然没有得到直接的答案,可能是我的问题不清楚。在CHM中,您只需放置单个节点(对象),我知道这些节点保证是同步的,但是这些节点所引用的几个对象(这些节点中的字段)又如何呢?