0

现在我们有

Load A
StoreStore
Store B

有没有可能实际的执行顺序如下

StoreStore
Store B
Load A

如果可能,如何解释似乎违反The Java volatile Happens-Before Guarantee.

据我所知,volatile语义是使用下面的JMM内存屏障添加策略实现的

insert a StoreStore before volatile variable write operation
insert a StoreLoad after volatile variable write operation
insert a LoadLoad after volatile variable read operation
insert a LoadStore after volatile variable read operation

现在如果我们有两个java线程如下

线程 1

Load A
StoreStore
Store volatile B

线程 2

Load volatile B
Load C

根据“The Java volatile Happens-Before Guarantee”,<code>Load A应该是happens-before Load Cwhen Load volatile Bis after Store volatile B,但如果Load A可以重新排序为“after Store volatile B”,如何保证Load A is before Load C

4

2 回答 2

1

从技术上讲,Java 语言没有内存屏障。相反,Java 内存模型是根据发生在关系之前指定的;有关详细信息,请参阅以下内容:

您正在讨论的术语来自The JSR-133 Cookbook for Compiler Writers。正如文档所说,它是编写实现 Java 内存模型的编译器的人的指南。它解释了JMM 的含义,显然不打算成为官方规范。JLS 是规范。

JSR-133 Cookbook 中关于内存屏障的部分根据它们约束特定加载和存储序列的方式对它们进行分类。对于StoreStore障碍,它说:

顺序:Store1; StoreStore; Store2 确保 Store1 的数据在与 Store2 关联的数据和所有后续存储指令之前对其他处理器可见(即刷新到内存)。通常,StoreStore在不能保证从写入缓冲区和/或高速缓存到其他处理器或主存储器的刷新的严格排序的处理器上需要屏障。

如您所见,StoreStore障碍仅限制store操作的行为。

在您的示例中,您有 aload后跟 a storeStoreStore屏障的语义与load操作无关。因此,您建议的重新排序是允许的。

于 2019-10-01T14:25:38.730 回答
0

这只是回答您问题的更新部分。

首先,您提供的示例不是 Java 代码。因此我们不能对它应用 JMM 推理。(只是为了让我们清楚这一点。)

如果您想了解 Java 代码的行为方式,请忘记内存屏障。Java 内存模型告诉您为使内存读取和写入具有保证行为所需的一切。为了推理(正确的)行为,你需要知道的一切。所以:

  • 编写你的 Java 代码
  • 分析代码以确保在线程需要读取另一个线程写入的值的所有情况下,在链之前都有适当的发生。
  • 将您的(正确的)Java 代码编译为机器指令的问题留给编译器。

查看您示例中的伪指令序列,它们没有多大意义。我不认为真正的 Java 编译器会(在内部)在编译真正的 Java 代码时使用这样的障碍。相反,我认为StoreLoad在每次易失性写入之后和每次易失性读取之前都会有一个内存屏障。

让我们考虑一些真实的 Java 代码片段:

public int a;
public volatile int b;

// thread "one"
{
  a = 1;
  b = 2;
}

// thread "two"
{ 
  if (b == 2) {
      print(a);
  }
}

现在假设线程“二”中的代码在线程“一”之后执行,将会有这样一个发生前链:

  • a = 1发生之前b = 2
  • b = 2发生之前b == 2
  • b == 2发生之前print(a)

除非涉及其他代码,否则发生之前的链意味着线程“二”将打印“1”。

笔记:

  1. 编译代码时无需考虑编译器使用的内存屏障。
  2. 障碍是特定于实现的并且是编译器内部的。
  3. 如果您查看本机代码,您将看不到内存屏障本身。您将看到具有所需语义的本机指令,以确保存在(隐藏的)内存屏障。
于 2019-10-12T04:31:40.330 回答