获取和释放围栏的这些定义是否不正确?

时间:2014-11-18 21:39:55

标签: concurrency lock-free memory-fences

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

•获取围栏。确保在围栏移动后不会有任何负载或存储。在它之前的指示可能仍然在围栏之后移动。

•释放围栏。确保在栅栏后栅栏移动之前没有载荷或存储。之后的说明可能仍然发生在围栏之前。

我的问题是:如何允许某个操作在某些事情发生之前发生,但之后就不会发生。这很难解释,但这些陈述对我来说都像鸡或鸡蛋问题。

1 个答案:

答案 0 :(得分:0)

我将尝试基于Java volatile语义来解释这一点。将一些值写入volatile变量发生 - 之前可以通过其他线程从此变量读取此值。如何实现?让我们仔细看看某些指令:

  • 易失性读取,即从volatile变量中读取值;
  • 正常读取,即从非易失性变量中读取值;
  • 易失性写;
  • 正常写;

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

好吧,volatile修饰符禁止某些重新排序 - volatile write 无法在正常写入之前放置, volatile read 不能放在正常读取之后。

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

  • JVM和CPU可以对您在程序中编写的指令执行多种类型或重新排序;
  • 记忆障碍(围栏)禁止一些重新排序,具体取决于围栏类型;说到你的例子,获取围栏确保在围栏之前发生的所有操作都不会发生在它之后;类似于第二个 - 所有在围栏之后发生的操作,都不会在围栏之前移动;我的volatile考试说明了这一点。