自动优化对象变量的 L 缓存?
Auto optimisation for L cache for object's variables?
坦率地说,这是 , inspired by this answer:
的延续
假设我们有一个 class:
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
值读取操作。
问题是:是否存在任何 L 缓存的自动优化可以缓存 x
变量的 null
值,因此线程 T2
将读取其缓存值?
换句话说,在这种特定情况下我们是否需要 volatile
修饰符?
T1 和 T2 按顺序执行 cache is coherent,尤其是在这个顺序用例中。
因此时间 4 的 T2 不可能获得空值。
创建线程时,它会看到创建前设置的任何值。
在 Javadoc for java.util.concurrency for Java 11 under Memory Visibility Properties and JLS-17.4.5 for Java 8 states
A call to start on a thread happens-before any action in the started thread.
注意:当一个线程重新读取它已经在其缓存中的缓存行中的值时,它只读取缓存的值。如果它读取以前从未读取过或不再在缓存中的缓存行,则它不会读取过时值。
坦率地说,这是
假设我们有一个 class:
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
值读取操作。
问题是:是否存在任何 L 缓存的自动优化可以缓存 x
变量的 null
值,因此线程 T2
将读取其缓存值?
换句话说,在这种特定情况下我们是否需要 volatile
修饰符?
T1 和 T2 按顺序执行 cache is coherent,尤其是在这个顺序用例中。
因此时间 4 的 T2 不可能获得空值。
创建线程时,它会看到创建前设置的任何值。
在 Javadoc for java.util.concurrency for Java 11 under Memory Visibility Properties and JLS-17.4.5 for Java 8 states
A call to start on a thread happens-before any action in the started thread.
注意:当一个线程重新读取它已经在其缓存中的缓存行中的值时,它只读取缓存的值。如果它读取以前从未读取过或不再在缓存中的缓存行,则它不会读取过时值。