根据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中其他对象的对象,由于与上述相同的原因,在多线程环境中,该对象图上的某些更新可能不会同步。以上例子?
虽然对象图中的根节点将始终在地图中为所有线程更新,但是如果其他对象在根节点中被称为字段,那么它们是不是最终的还是易变的?
答案 0 :(得分:2)
在回答我自己的问题时,我应该在提问之前阅读完整的章节。这是后面章节的内容:
可变物体:如果物体在施工后可以修改,则安全 发布仅确保已发布状态的可见性。 同步必须不仅用于发布可变对象,而且 每次访问对象时也要确保可见性 后续修改。为了安全地共享可变对象,他们必须 安全地发布,并且可以是线程安全的,也可以是锁定保护。
因此,在多线程环境中使用CHM或任何线程安全集合是不安全的,除非您将更改同步到CHM中的可变对象或这些对象是不可变的。
答案 1 :(得分:1)
ConcurrentHashMap保证所有带引用的操作(链接到对象),保存在ConcurrentHashMap中,都是线程安全的,但是,当然,ConcurrentHashMap不能保证每个对象的线程安全,带引用(链接) )存储在ConcurrentHashMap中。