vin*_*yag 9 java concurrency multithreading
实践中的Java并发书给出了不安全发布的一个例子
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.");
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码似乎是线程安全的.如果n是公共变量,它将不是线程安全的.这本书的例子是错的吗?
axt*_*avt 10
安全发布是关于内存可见性的.内存可见性的概念比其他线程安全问题(例如竞争条件)有点棘手.
当一个线程按特定顺序执行的操作看起来以不同的顺序执行另一个线程时,会出现内存可见性问题(这可能是由编译器或CPU进行的优化引起的).
在你的情况下:
// Thread A
h = new Holder(42);
// Thread B
h.assertSanity();
Run Code Online (Sandbox Code Playgroud)
对于线程A,n
肯定是在之前初始化的h
.
但是由于缺乏安全发布,因此线程B不能保证相同.线程B可能h
在初始化状态下看到,但是n
不会被初始化.此外,n
线程B所观察到的状态可能在评估期间发生变化n != n
,从而导致assertSanity()
异常.
请注意,在所有情况下都不会发生此问题.您可能永远不会看到这种情况发生,但Java Memory Model在这种情况下并不保证正确性.
归档时间: |
|
查看次数: |
1185 次 |
最近记录: |