Ser*_*aev 5 java multithreading java-memory-model
Run Code Online (Sandbox Code Playgroud)public class ReOrdering implements Runnable { int one, two, three, four, five, six; volatile int volaTile; @Override public void run() { one = 1; two = 2; three = 3; volaTile = 92; int x = four; int y = five; int z = six; } }的任务
one,two并且three可以重新排序,只要他们所有发生之前volatile写.同样,x,y和z作为陈述可能被重新排序volatile写个个之前发生.该volatile操作通常称为内存屏障.保证之前发生的事情确保volatile变量的读写指令 不能在内存屏障上重新排序.在保证具有另一种效果之前发生:当线程写入
volatile变量时,在写入volatile变量之前由线程更改的所有其他变量(包括非易失性)也会刷新到主存储器.当线程读取volatile变量时,它还会读取所有其他变量(包括非易失性),这些volatile变量与变量一起刷新到主存储器 .
©Bruce Eckel"On Java 8"
我一定是误解了一些东西,因为这段代码不能像这样工作
public class Reordering {
private int x;
private volatile int y;
public void writer() {
x = 1;
y = 2;
}
public void reader() {
if (y == 2) {
if(x == 0) {
// X assignment is happens-before for
// volatile Y assignment
// so X can't be 0 when Y equals 2
throw new RuntimeException();
}
x = 0;
y = 0;
}
}
public static void main(String[] args) {
Reordering reordering = new Reordering();
Thread thread = new Thread(() -> {
while (true) {
reordering.writer();
}
});
thread.setDaemon(true);
thread.start();
while (true) {
reordering.reader();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我认为,当编写器踏板刚刚设置时,问题可能发生x=1,而读取器已经在if块中(在变量赋值之前):
reader writer state
----------------- ------ --------
stops before x=0 x=1, y=2
x=1 x=1, y=2
x=0 x=0, y=2
y=0 x=0, y=0
y=2 x=0, y=2
reader will throw
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
83 次 |
| 最近记录: |