我正在阅读JSR-133中的Java内存模型,我无法理解这种行为是如何被接受的:

谁能解释一下吗?
发布于 2021-10-11 14:05:06
CPU必须确保线程中对X的写入不会影响后续分配到其相关的RX内存位置。它没有说明它从哪里得到它要写的值。
所以,在线程1中,CPU表示
“噢,我需要读X",于是开始了一个读操作。
然后上面写着
“并且我需要写到X",所以将队列中的值放在一个写队列中
线程2也做同样的事情。
“噢,我要读X”,开始读。
“我需要写到X",并排队写。
现在,我们有两个等待读和两个排队写。
如果CPU体系结构说,一个核心上的读取可能会询问另一个核心的写入队列,那么两个核心都可以彼此读取对方未完成的对X的写入,因此您将两个值跨核拉出,最终从该线程分配给RX内存位置。
当您在指令流中放置内存屏障时,它将防止这种过于急切的排队写入读取。
发布于 2021-10-11 10:03:14
8.1内存模型允许的令人惊讶的行为
图12显示了一个很小但很有趣的例子。行为r1 == 2和r2 == 1是一种合法行为,尽管很难看出它是如何发生的。编译器不会重新排序每个线程中的语句;这段代码绝不能导致r1 == 1或r2 == 2。然而,早期执行写入的处理器体系结构可能会允许行为r1 == 2和r2 == 1,但在它们之前的本地读取中,它们在程序顺序上是不可见的。这种行为虽然令人惊讶,但Java内存模型允许这样做。为了在内存模型中得到这个结果,我们提交了两个写,然后都读取。
不知怎么的,CPU决定写x早于读x。这个例子所说明的是,这是有效的行为,或多或少,这是一个被接受为有效行为的例外。
英特尔Itanium CPU可以产生这样的行为。
因此,与其:
//Thread 1
int x = 0;
int r1 = x;
x = 1;
//Thread 2
int x = 0;
int r2 = x;
x = 2;这种情况会发生:
//Thread 1
int x = 0;
x = 2; //from Thread 2
int r1 = x;
//Thread 2
int x = 0;
x = 1; //from Thread 1
int r2 = x;这是完全正确的。(已被接受的例外情况)
https://stackoverflow.com/questions/69524145
复制相似问题