我正在研究同步和volatile变量如何在java中工作,我遇到了一个名为read and write barrier的概念。任何人都可以帮助我理解这个术语的含义
答案 0 :(得分:6)
(上面的答案非常完整),我只想用简单的方案来演示这个概念
Thread 1 Thread 2
|
|
| |
| |
| Everything Thread 1 |
| wrote before here |
| |
| |
_ _ _ _ _ _ _ _ _ _ |
( write barrier) (happens before) (read barrier) |
| _ _ _ _ _ _ _ _
|
| is guaranteed |
| to be visible to |
| Thread 2 |
| |
答案 1 :(得分:3)
内存屏障是代码中的概念“行”,它阻止编译器进行某些优化,并可能向处理器插入特殊的“同步”命令。通常,编译器可以查看特定方法,并查看某些指令可以在不改变代码含义的情况下移动。例如,如果你有
int x = 0, y = 0;
x++;
y++;
如果编译器认为有一些好处,它可以改为输出
的代码y++;
x++;
但是,如果x
和y
是某个类中的字段,以便可以从其他线程看到它们,则另一个线程可能会在您的方法运行时修改这些值。
内存屏障迫使编译器重新检查特定变量的值(在Java中,那些是volatile
和Atomic*
类的值),以防某些其他线程修改它们而方法是一直在运行,它使编译器不会进行可能会意外更改计算结果的重新排序。在支持多核/处理器的系统上,编译器还会强制处理器检查以确保其他处理器或硬件设备在此期间未修改变量。 Java(从Java 5开始)有一套非常明确的规则,用于解决这个问题,称为happens-before。
This FAQ有一些有用的解释,这些解释是在Java Memory Model开发时编写的。请注意,虽然内存屏障的概念是跨语言的,但大多数语言没有像Java那样明确定义它们的规则。
答案 2 :(得分:0)
当您输入同步的代码块时,您会传递“读取屏障”,当它退出时,您将通过“写屏障”。
用于引用volatile属性,并在Threads需要更新volatile属性的值时给出指示。如果其他人通过了写屏障,他们应该在通过读屏障时更新它。
类似于从volatile属性读取使得线程通过读屏障并且写入volatile属性会使您通过写屏障,因此比同步块更精细。
答案 3 :(得分:0)
读写障碍用于通过JVM在最低级别实现Java内存模型的语义。
然而,Java语言规范中没有这个术语,只有发生在关系之前的原因。特别是
如果程序中两个操作之间存在匹配发生的关系,则可以保证这两个操作将按顺序一致的顺序执行(即好像只有一个线程并且没有不直观的重新排序)。
编写正确的多线程程序不需要深入研究JVM的实现细节。但是,如果你想要血腥的细节,JSR-133 cookbook是一个有趣的读物。