坦率地说,这是this my question的延续,受到以下答案的启发:https://stackoverflow.com/a/53262717/1479414
假设我们有一堂课:
public class Foo {
private Integer x;
public void setX(Integer x) {
this.x = x;
}
public Integer getX() {
return this.x;
}
}
当我们只有两个与x
变量交互的线程时,让我们考虑一种非常特殊的情况:
在时间1,创建了线程T1
在时间2,T1设置值:foo.setX(123);
在时间3,创建了线程T2
在时间4,T2读取值:foo.getX();
没有其他线程与此值交互。两种操作仅发生一次。
因此,在线程T2执行其工作之前,没有明显的x
值读取操作。
问题是:是否存在任何可以对null
变量的x
值进行缓存的L缓存的自动优化,所以线程T2
将读取其缓存的值?
换句话说,在这种特定情况下,我们是否需要volatile
修饰符?
答案 0 :(得分:4)
创建线程时,它将在创建之前看到设置的任何值。
在Memory Visibility Properties和JLS-17.4.5 for Java 8状态下的Java 11 for Java.util.concurrency的Javadoc中
在启动的线程中执行任何操作之前,发生了在线程上启动调用。
注意:当线程重新读取它已经在其高速缓存中的高速缓存行中的值时,该线程仅读取高速缓存的值。如果它读取从未读取过的缓存行或不再位于缓存中,则不会读取过时的值。
答案 1 :(得分:1)
T1和T2依次执行,cache is coherent顺序执行,尤其是在这种顺序使用情况下。
因此,在时间4处T2不可能获得空值。