【发布时间】:2015-03-12 02:10:57
【问题描述】:
我遇到了以下说法:“读取或写入 volatile 变量会施加内存屏障,其中整个缓存都被刷新/无效。”
现在考虑以下执行场景:
初始volatile boolean barrier;
初始int b = 0;
线程 1 b = 1; // write1
线程 1 barrier = true; // write2
线程 2 barrier = true; // write3
线程 2 print(b); // r1
问题:线程 2 是否保证打印 1?
根据声明,我会回答是:线程 1 在 write2 上刷新其缓存(以便b = 1 最终进入主内存),线程 2 在 write3 上使其缓存无效(以便它将读取 b来自主内存)。
但是,在相关的JLS sections 中,我无法为这种行为找到保证,因为 write3 是写入,而不是读取。因此,以下看似关键的条款不适用:
对 volatile 变量 v(第 8.3.1.4 节)的写入与任何线程对 v 的所有后续读取同步(其中“后续”是根据同步顺序定义的)。 p>
我是否遗漏了一些其他信息,或者我可能误解了什么?
(相关问题:
【问题讨论】:
-
如何确保线程 2 中的
write3发生在线程 1 中的write1之后?如果您可以确保写入按该顺序发生,那么我猜b == 1将在线程 2 中看到。 -
@jepio:我并不是要确保任何事情——只是描述一个可能的执行场景。那么,在这种情况下,线程 2 是否无法读取 b 的缓存/陈旧值?
标签: java memory concurrency keyword volatile