【发布时间】:2013-08-31 09:39:02
【问题描述】:
我正在研究 java 中同步和 volatile 变量的工作方式,我遇到了一个名为 read and write barrier 的概念。谁能帮我理解这些术语的含义
【问题讨论】:
-
你看1787450了吗?
-
真的很有帮助..谢谢
标签: java multithreading
我正在研究 java 中同步和 volatile 变量的工作方式,我遇到了一个名为 read and write barrier 的概念。谁能帮我理解这些术语的含义
【问题讨论】:
标签: java multithreading
(上面的答案都挺完整的),我只是想用一个简单的方案来演示一下这个概念
Thread 1 Thread 2
|
|
| |
| |
| Everything Thread 1 |
| wrote before here |
| |
| |
_ _ _ _ _ _ _ _ _ _ |
( write barrier) (happens before) (read barrier) |
| _ _ _ _ _ _ _ _
|
| is guaranteed |
| to be visible to |
| Thread 2 |
| |
【讨论】:
内存屏障是代码中的概念性“线”,可防止编译器进行某些优化,并可能向处理器插入特殊的“同步”命令。通常,编译器可以查看特定方法,并看到某些指令可以在不改变代码含义的情况下移动。例如,如果您有
int x = 0, y = 0;
x++;
y++;
如果编译器认为有一些好处,它可以改为输出代码
y++;
x++;
但是,如果 x 和 y 是某个类中的字段,以便可以从其他线程看到它们,则其他线程可能会在您的方法运行时修改值。
内存屏障强制编译器重新检查特定变量的值(在 Java 中,这些是 volatile 和 Atomic* 类),以防在方法运行时其他线程修改了它们,并且它可以防止编译器进行可能意外更改计算结果的重新排序。在支持多个内核/处理器的系统上,编译器还将强制处理器检查以确保其他一些处理器或硬件设备在此期间没有修改变量。 Java(从 Java 5 开始)有一套非常明确的规则来说明其工作方式,称为happens-before。
This FAQ 有一些有用的解释,这些解释是在开发 Java 内存模型时编写的。请注意,虽然内存屏障的概念是跨语言的,但大多数语言没有像 Java 那样明确定义的规则。
【讨论】:
当你进入一个同步的代码块时,你会通过“读屏障”,当它退出时,你会通过“写屏障”。
Is 用于引用 volatile 属性,并在线程需要更新其 volatile 属性值时给出指示。如果其他人通过了写屏障,他们应该在通过读屏障时更新它。
从 volatile 属性中读取类似的内容会使您的线程通过读屏障,而写入 volatile 属性会使您通过写屏障,因此比同步块更细粒度。
【讨论】:
读写屏障被JVM用来在最底层实现Java内存模型的语义。
但是,Java 语言规范中没有该术语,它仅根据 happens-before 关系进行解释。特别是
当您的程序中的两个操作之间存在先发生关系时,您可以保证这两个操作将以一致的顺序执行(即,就好像只有一个线程并且没有不直观的重新排序)。
为了编写一个正确的多线程程序,没有必要深入研究 JVM 的实现细节。但是,如果您想了解血淋淋的细节,JSR-133 cookbook 是一本有趣的书。
【讨论】: