【问题标题】:Java Memory Model ActionsJava 内存模型操作
【发布时间】:2015-09-09 02:06:46
【问题描述】:

我正在尝试理解Java Memory Model,但我在操作方面遇到了一些麻烦。我理解动作的定义为t, k, v, u>,但我不太明白程序是如何分解成动作的,以及这些动作有多抽象。

我的第一个假设是动作是原子的。 var1 = var2 将分为两个动作 - 读取 var2 和写入 var1,但一个示例 here 表明 var1 = var2 本身就是一个动作。所以每个动作对应源码中的一条语句。

这如何与 if 语句一起使用?例如,如果我们有if(r1 == r2 && r3 == r4) { ... },整个语句会是一个动作,还是分成多个动作(如果是,相应的动作如何保持“连接”作为 if 语句)?

【问题讨论】:

    标签: java concurrency memory-model java-memory-model


    【解决方案1】:

    动作在JLS 17.4.2中定义,特别关注“线程间动作”:

    线程间动作是一个线程执行的动作,可以被另一个线程检测或直接影响。 ...本规范仅涉及线程间操作。

    这些操作的完整列表在链接中(这里不值得完整复制),但它包括变量的读取和写入。

    var1 = var2 的问题取决于var1var2 是什么。如果它们都是类上的字段,那么它们是两个单独的操作(读取var2 并写入var)。如果它们中的任何一个是局部变量,则其状态属于方法的堆栈帧,它本质上是线程局部的,因此不是线程间操作。

    例如,如果var2 是一个字段并且var1 是一个局部变量,那么唯一的线程间操作是读取var2 — 将该值写入局部变量是 不是线程间动作,因为它只能被本地堆栈帧所属的线程观察到。

    同样,if (r1 == r2 && r3 == r4) 最多可以有 4 个动作:四个变量的读取,如果它们是字段。 ==&& 操作的结果是线程本地的,因此不算作线程间操作。

    【讨论】:

    • 假设我们有一个语句r1 = x,其中x 是共享变量x,而r1 是某个线程的本地变量。根据我链接的第二篇论文,这将作为r1 = x 的行动提交。但是,只有x的读取可以被另一个线程检测或直接影响,那为什么还要考虑r1呢?
    • r1 仍在考虑中”是什么意思?动作是读取x。读取需要从某处其他地方读取数据;在这种情况下,r1 只是“其他地方”,很可能只是一个寄存器。
    • 谢谢 yshavit,我想我正在关注。因此,如果该示例中的r1 也是一个共享变量,那么r1 = x 将是两个独立的操作——read xwrite r1 = value of x,对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2019-04-06
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    相关资源
    最近更新 更多