gpt4 book ai didi

Java同步-不正确的发布

转载 作者:行者123 更新时间:2023-11-30 08:01:17 25 4
gpt4 key购买 nike

这是《Java 并发实践》一书的摘录:

// Unsafe publication
public Holder holder;
public void initialize() {
holder = new Holder(42);
}

... Because of visibility problems, the Holder could appear to another thread to be in an inconsistent state, even though its invariants were properly established by its constructor! This improper publication could allow another thread to observe a partially constructed object. ...

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.");
}
}

... But far worse, other threads could see an up-to-date value for the holder reference, but stale values for the state of the Holder. ...

To make things even less predictable, a thread may see a stale value the first time it reads a field and then a more up-to-date value the next time, which is why assertSanity can throw AssertionError. ... the Object constructor first writes the default values to all fields before subclass constructors run. It is therefore possible to see the default value for a field as a stale value.

我的问题:

似乎只有两种情况下,assertSanity() 会抛出 AssertionError - 当“Holder”实例处于实例化过程中并且“n”的默认值尚未设置为“42”时。

  1. 在构造函数退出之前(在构造函数初始化“n”字段之前),Java 会将部分创建的对象放入“holder”引用中。另一个线程将尝试在此部分创建的对象上调用“assertSanity”。因此“n != n”操作必须足够长才能发生断言错误。

  2. 当assertSanity() 正在进行时,本地缓存的“holder”突然变得可见。

还有其他情况吗?

谢谢大家!

最佳答案

由于重新排序,你无法真正思考“这发生在那之后”。例如

Java will put partially created object in "holder" reference before constructor exits (before constructor initialize "n" field)

实际上可能会出现这样的情况:一个线程观察到构造函数已经退出并且对象已经初始化,但是另一个线程可能看到了引用(因此它也认为构造函数已经退出),但是对象的字段还没有已为此线程初始化。

因此,事情变得真正不可预测,因为如果没有适当的同步,不同的线程可能会以不同的顺序观察到状态变化,或者根本看不到。在这里推理所有可能的情况几乎是不可能的:(

我强烈建议您阅读《Java 并发实践》一书中的“Java 内存模型”部分。

关于Java同步-不正确的发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31875443/

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