1

在 Joe Duffy 的并发编程书中,他定义了获取和释放栅栏,如下所示:

• 获得栅栏。确保围栏之后的负载或存储不会在围栏之前移动。之前的指令可能仍然会在围栏之后移动。

• 释放围栏。确保栅栏之前的负载或存储不会在栅栏之后移动。之后的指令可能仍然发生在栅栏之前。

我的问题是:如何允许操作在某事之前发生,但在之后被阻止发生。这很难解释,但对我来说,这两种说法都像是鸡或蛋的问题。

4

1 回答 1

0

我将尝试基于 Javavolatile语义来解释这一点。将某个值写入volatile变量发生在其他线程可以从该变量中读取该值之前。这是如何实现的?让我们仔细看看某种指令:

  • volatilevolatile read,即从一个变量中读取一个值;
  • 正常读取,即从非易失性变量中读取值;
  • 易失性写入;
  • 正常写入;

现在,Java 内存模型为您提供了一些行为保证,其中之一是我在上面写的。问题是——这是如何实现的?

好吧,volatile修饰符禁止某些类型的重新排序- volatile write不能放在normal write之前,volatile read不能放在normal read之后。

如何将其与您的问题联系起来?我将尝试根据我上面写的内容来制定答案。

  • JVM 和 CPU 可以对您在程序中编写的指令执行多种类型或重新排序;
  • 内存屏障(栅栏)禁止某些重新排序,具体取决于栅栏类型;谈到您的示例,获取围栏确保将在围栏之前发生的所有操作都不会在围栏之后发生;与第二个类似 - 所有应该在围栏之后发生的操作,都不会移动到围栏之前;我的例子volatile说明了这一点。
于 2015-02-21T13:30:43.133 回答