我已经知道,如果我从另一个线程写入非易失性字段,他可能会缓存它,这样所有其他线程就看不到实际值。但如果我举个例子 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;
}
}
1条答案
按热度按时间nfs0ujit1#
在本例中,线程中如何更新某些内容的机制(无论是直接字段访问还是通过setters)并不重要。jls 17.4.5规定“线程上对start()的调用发生在已启动线程中的任何操作之前。”在单个线程中,“如果x和y是同一线程的操作,并且x按程序顺序排在y之前,则[x在y之前发生]”。在这种情况下,一个方法设置器或字段赋值会使一个值对原始线程可见,也会使该值对新启动的线程可见。大体上,只要所查看的对象没有发生变化,并且查看状态的尝试没有发生变化(例如linkedhashmap#get with accessorder=true),调用start()的线程在调用start()时可以看到的任何内容对新线程也同样可见。