jvm是否会更新所有线程的字段值,使用的是happens before,而不直接为字段赋值?

tpgth1q7  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(244)

我已经知道,如果我从另一个线程写入非易失性字段,他可能会缓存它,这样所有其他线程就看不到实际值。但如果我举个例子 start() 在将值赋值给field之后,jvm将为所有其他线程更新这个值。但是,如果我将执行相同的操作,但不会直接将值赋给字段,jvm是否会更新此字段的值,如下所示: object.field = 100 但是使用调用方法 object.setFiled(100) .

public class Main {
int value;

public static void main(String[] args) {
    Main main = new Main();
    main.value = 100;
    new Thread(() -> System.out.println(main.getValue())).start();

在这种情况下,所有其他线程的字段值肯定是相同的

}

public int getValue() {
    return value;
}
}

public class Main {
private int value;

public static void main(String[] args) {
    Main main = new Main();
    main.setValue(100);
    new Thread(() -> System.out.println(main.getValue())).start();

但在这种情况下结果会是一样的吗?

}

public int getValue() {
    return value;
}

public void setValue(int value) {
    this.value = value;
}
}
nfs0ujit

nfs0ujit1#

在本例中,线程中如何更新某些内容的机制(无论是直接字段访问还是通过setters)并不重要。jls 17.4.5规定“线程上对start()的调用发生在已启动线程中的任何操作之前。”在单个线程中,“如果x和y是同一线程的操作,并且x按程序顺序排在y之前,则[x在y之前发生]”。在这种情况下,一个方法设置器或字段赋值会使一个值对原始线程可见,也会使该值对新启动的线程可见。大体上,只要所查看的对象没有发生变化,并且查看状态的尝试没有发生变化(例如linkedhashmap#get with accessorder=true),调用start()的线程在调用start()时可以看到的任何内容对新线程也同样可见。

相关问题