繁体   English   中英

Java的状态比较不一致

[英]Inconsistent State Comparison Java

Java Concurrency In Practice中 ,给出了一个示例*来演示可见性问题,其中两个不同的线程由于缺少同步而可能看不到任何特定可变对象的最新状态。

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

在此特定示例中,该书指出应首先初始化线程“ A”并通过线程不安全的方式发布它,例如:

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

然后,线程“ B”调用holder.assertSanity() ,由于状态不一致,很有可能引发AssertionError

现在,我了解了该参数的基本前提,即对可变变量所做的更改可能永远不会被另一个线程观察到。 但是我在这里感到困惑的是,它正在比较相同的(或我认为)参考n != n

这不比较可变基本字段private int n吗? 不管现在线程A的n值可以为42,线程B的n值可以为0(默认值),无论是否直接调用以检查同一线程中的值是否一致 即在线程A中调用assertSanity()将检查是否42 != 42 ,在线程B中是否为0 != 0

*参考3.5安全出版物中的清单3.14和3.15。

问题在于,在表达式n != n ,变量n将被加载两次(假设未对字节码进行优化)。 在这两个负载之间,另一个线程可以更改该值。

在线程B中比较n != n ,B检索n两次。 同时,在线程A中运行的构造函数会将n的值从默认0修改为42。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM