在Java Concurrency in Practice中我认为令人惊讶的一个例子(至少我)是这样的:
public class Foo {
private int n;
public Foo(int n) {
this.n = n;
}
public void check() {
if (n != n) throw new AssertionError("huh?");
}
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是(至少对我来说)声称这不是线程安全的,不仅它不安全,而且检查方法也有可能抛出断言错误.
解释是,如果没有同步/标记n为volatile,则不同线程之间没有可见性保证,并且n的值可以在线程读取时更改.
但我想知道它在实践中发生的可能性有多大.或者更好,如果我能以某种方式复制它.
所以我试图编写会触发断言错误的代码,没有运气.
有没有直接的方法来编写一个测试,证明这个可见性问题不仅仅是理论上的?
或者它是否在最近的JVM中发生了变化?
编辑:相关问题:非线程安全对象发布
但我想知道它在实践中发生的可能性有多大.
非常不可能的esp,因为JIT可以n变成一个局部变量而只读一个.
极不可能的线程安全漏洞的问题在于,有一天,您可能会更改一些无关紧要的内容,例如您选择的处理器或JVM,并且突然您的代码会随机中断.
或者更好,如果我能以某种方式复制它.
不保证您也可以重现它.
有没有直接的方法来编写一个测试,证明这个可见性问题不仅仅是理论上的?
在某些情况下,是的.但是这个是难以证明的,部分原因是因为JVM没有被阻止比JLS说的最小的线程更安全.
例如,HotSpot JVM通常会执行您期望的操作,而不仅仅是文档中的最小值.例如,根据javadoc,System.gc()只是一个提示,但默认情况下,HotSpot JVM每次都会这样做.
| 归档时间: |
|
| 查看次数: |
105 次 |
| 最近记录: |