【问题标题】:Auto optimisation for L cache for object's variables?对象变量的 L 缓存自动优化?
【发布时间】:2019-04-15 06:12:17
【问题描述】:

坦率地说,这是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 值读取操作。

问题是:L 缓存是否存在任何自动优化,可以缓存x 变量的null 值,因此线程T2 将读取其缓存值? 换句话说,在这种特殊情况下,我们是否需要 volatile 修饰符?

【问题讨论】:

    标签: java multithreading volatile cpu-cache


    【解决方案1】:

    当你创建一个线程时,它会看到创建之前设置的任何值。

    Memory Visibility PropertiesJLS-17.4.5 for Java 8 状态下的 Java 11 的 java.util.concurrency 的 Javadoc 中

    在线程上启动的调用发生在已启动线程中的任何操作之前。

    注意:线程仅读取缓存的值,当它重新读取缓存行中的值时,它已经在其缓存中。如果它读取一个以前从未读取过或不再在缓存中的缓存行,它就不会读取过时的值。

    【讨论】:

    • 非常感谢您的回答!听起来合乎逻辑的是,当创建一个新线程时,它应该看到任何变量的实际值。但是,是否可以通过一些规范链接来加强这一声明?
    • @Andremoniy 我已添加报价。
    【解决方案2】:

    T1 和 T2 是顺序执行的,cache is coherent,尤其是在这种顺序用例中。

    所以 T2 在时间 4 是不可能得到空值的。

    【讨论】:

    • 所以你假设 CPU 缓存与 volatile-problem 无关?
    • 我不这么认为。我假设因为 T1 和 T2 的执行是顺序的,所以缓存会是一致的(没有并发问题)
    • 这是我的问题:有些人声称存在独立于现有线程的自动优化
    • 能否详细说明?
    • 我不知道如何详细说明。据说有一个“L* 缓存的自动优化”,它可以导致空值被缓存并因此传递给线程 T2。那是我的问题:类似的东西真的存在吗?
    猜你喜欢
    • 2014-05-21
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    相关资源
    最近更新 更多