我目前正在学习Java内存模型,我发现了不同类型的Actions。
其中有两个我不完全理解:
请解释这两种动作类型,并举例说明它们以及有关编译器重新排序和发生在关系之前的特殊属性。哦,本地电话也是外部行动吗?
我认为如果没有什么特别的话,他们就不会定义线程分歧行为。那么是什么让它们变得特别,以便将它们定义为一种特殊的行为呢?
答案 0 :(得分:4)
现有答案已正确定义了这些操作的内容。
关于重新排序:请看以下线程分歧操作的示例:
class ThreadDivergence {
int foo = 0;
void thread1() {
while (true); // thread-divergence action
foo = 42;
}
void thread2() {
assert foo == 0;
}
}
你会期望这个断言永远不会失败。如果没有线程分歧操作,则无法保证这一点,因为设置foo = 42
的无法访问的定义可以重新排序以便首先执行。这是JMM禁止的。
同样,添加外部行动以避免出现意外结果:
class Externalization {
int foo = 0;
void method() {
jni(); // external action
foo = 42;
}
native void jni(); /* {
assert foo == 0;
} */
}
假设实现了JNI方法以运行相同的断言,您不会期望这会失败。 JIT编译器无法确定任何外部的结果,因此JMM也禁止这样的重新排序。
答案 1 :(得分:0)
如果我理解正确,外部操作在Java VM进程之外是可见的,例如显示窗口,写入文件或连接到套接字。
Thread Divergence Action必须进入无限while(true)
循环。