问题描述
我目前正在学习Java内存模型,并且想到了各种操作.
I'm currently learning about the Java Memory Model and I came about the different kinds of Actions.
其中有两个我不完全了解:
There are two of them which I don't fully understand:
- 外部动作和
- 线程分歧动作
- External Actions and
- Thread divergence actions
请说明这两种操作类型,并为它们提供示例,并提供有关编译器重新排序和事前联系的特殊属性的示例.哦,本地调用也是外部操作吗?
Please explain those two action types and give examples for them and for their special properties regarding compiler-reordering and happens-before relation. Oh, and are native calls also external actions?
如果没有特别之处,我认为他们不会定义线程分歧动作.那么是什么使它们与众不同,因此需要将它们定义为一种特殊的动作?
I think they wouldn't define thread divergence actions if there was nothing special about them. So what makes them special so that they need to be defined as a special kind of action?
推荐答案
现有答案已经正确定义了这些操作是什么.
The existing answer already correctly defines what these actions are.
关于重新排序:请看下面的 thread-divergence 动作示例:
As for the reordering: look at the following example of a thread-divergence action:
class ThreadDivergence {
int foo = 0;
void thread1() {
while (true); // thread-divergence action
foo = 42;
}
void thread2() {
assert foo == 0;
}
}
您希望这个断言永远不会失败.如果没有线程发散动作,则无法保证,因为设置foo = 42
的不可达定义可以重新排序以首先执行. JMM禁止这样做.
You would expect this assertion to never fail. Without thread-divergence actions, this could not be guaranteed because the unreachable definition of setting foo = 42
could be reordered to be executed first. This is forbidden by the JMM.
类似地,添加了外部动作以避免令人惊讶的结果:
Similarly, external actions are added to avoid surprising outcomes:
class Externalization {
int foo = 0;
void method() {
jni(); // external action
foo = 42;
}
native void jni(); /* {
assert foo == 0;
} */
}
假设实现了JNI方法以运行相同的断言,则您不会期望此操作会失败. JIT编译器无法确定任何 external 的结果,以致JMM也禁止这种重新排序.
Assuming that the JNI method was implemented to run the same assertion, you would not expect this to fail. The JIT compiler cannot determine the outcome of anything external such that the JMM forbidds such reorderings, too.
这篇关于Java内存模型中的线程分歧动作和外部动作的示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!