首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java内存模型-令人惊讶的行为

Java内存模型-令人惊讶的行为
EN

Stack Overflow用户
提问于 2021-10-11 09:42:47
回答 2查看 252关注 0票数 3

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

谁能解释一下吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-11 14:05:06

CPU必须确保线程中对X的写入不会影响后续分配到其相关的RX内存位置。它没有说明它从哪里得到它要写的值。

所以,在线程1中,CPU表示

“噢,我需要读X",于是开始了一个读操作。

然后上面写着

“并且我需要写到X",所以队列中的值放在一个写队列中

线程2也做同样的事情。

“噢,我要读X”,开始读。

“我需要写到X",并排队写。

现在,我们有两个等待读和两个排队写。

如果CPU体系结构说,一个核心上的读取可能会询问另一个核心的写入队列,那么两个核心都可以彼此读取对方未完成的对X的写入,因此您将两个值跨核拉出,最终从该线程分配给RX内存位置。

当您在指令流中放置内存屏障时,它将防止这种过于急切的排队写入读取。

票数 1
EN

Stack Overflow用户

发布于 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可以产生这样的行为。

因此,与其:

代码语言:javascript
复制
//Thread 1
int x = 0;
int r1 = x;
x = 1;

//Thread 2
int x = 0;
int r2 = x;
x = 2;

这种情况会发生:

代码语言:javascript
复制
//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;

这是完全正确的。(已被接受的例外情况)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69524145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档