在ConcurrentHashMap中存储复杂对象

时间:2015-12-14 23:39:21

标签: java multithreading concurrency

根据Java Concurrency in Practice,下面的代码可以抛出断言错误:

如果发布线程以外的线程要调用 assertSanity,它可能抛出AssertionError

  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中其他对象的对象,由于与上述相同的原因,在多线程环境中,该对象图上的某些更新可能不会同步。以上例子?

虽然对象图中的根节点将始终在地图中为所有线程更新,但是如果其他对象在根节点中被称为字段,那么它们是不是最终的还是易变的?

2 个答案:

答案 0 :(得分:2)

在回答我自己的问题时,我应该在提问之前阅读完整的章节。这是后面章节的内容:

  

可变物体:如果物体在施工后可以修改,则安全   发布仅确保已发布状态的可见性。   同步必须不仅用于发布可变对象,而且   每次访问对象时也要确保可见性   后续修改。为了安全地共享可变对象,他们必须   安全地发布,并且可以是线程安全的,也可以是锁定保护。

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

答案 1 :(得分:1)

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