gpt4 book ai didi

Java 内存模型实践

转载 作者:行者123 更新时间:2023-11-30 09:06:07 24 4
gpt4 key购买 nike

我正在尝试学习 Java Memory Model , 但仍然无法理解人们在实践中如何使用它。

我知道很多只是依赖于适当的内存屏障(如 Cookbook 中所述),但实际上模型本身并不操作此类术语。该模型引入了在一组 Action 上定义的不同顺序,并定义了所谓的“格式良好的执行”。有些人试图使用这样的命令之一来解释内存模型限制,即“先发生”,但似乎该顺序,至少就其本身而言,并没有定义可接受的执行:

It should be noted that the presence of a happens-before relationship between two actions does not necessarily imply that they have to take place in that order in an implementation. If the reordering produces results consistent with a legal execution, it is not illegal

我的问题是如何验证某些代码或更改在实践中会导致“非法执行”(根据模型)?

更具体地说,让我们考虑一个非常简单的例子:

public class SomeClass {
private int a;
private int b;

public void someMethod() {
a = 2; // 1
b = 3; // 2
}
// other methods
}

很明显,根据程序顺序,在线程内 w(a = 2) 发生在 w(b = 3) 之前。编译器/优化器如何确保重新排序 1 和 2 不会产生“非法执行”(严格按照模型)?为什么如果我们将 b 设置为 volatile 它会呢?

最佳答案

您是在问 VM/JIT 如何分析字节码流吗?这太宽泛了,无法回答,整篇研究论文都是关于这个的。 VM 实际实现的内容可能会因版本而异。

或者问题仅仅是内存模型的哪些规则支配什么是“合法的”?对于正在执行的线程,内存模型已经做出强有力的保证,即给定线程上的每个操作似乎都按照该线程的程序顺序发生。这意味着如果 JIT 确定它为重新排序而实现的任何方法,则重新排序产生相同的可观察结果是合法的。

针对其他 线程(例如 volatile 访问)建立先行发生保证的操作的存在只会对合法的重新排序增加更多约束。

简化它可以被记住,因为在执行 happend-before establishing 操作时,before 中发生的所有事情似乎也(已经)发生在其他线程上。

对于您的示例,这意味着,在非 volatile (a, b) 的情况下,仅需要维护“似乎按程序顺序发生”(对执行线程)的保证,这意味着对写入的任何重新排序(a, b) 是合法的,甚至延迟它们直到它们被实际读取(例如,将值保存在 CPU 寄存器中并绕过主内存)也是有效的。如果 JIT 检测到在对象超出范围之前从未真正读取成员(准确地说,也没有使用它们的终结器),它甚至可以完全省略写入成员。

在您的示例中使 b 可变会更改约束,因为它发生在写入 b 之前,其他 读取 b 的线程也将保证看到 a 的最后更新。再次简化,happens-before 操作将一些可感知的顺序保证从执行线程扩展到其他线程。

关于Java 内存模型实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24553741/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com