考虑以下没有并发访问权限的Java类。
class C{
int x;
public void m1(int y){
this.x = y;
m2(y);
}
public void m2(int y){
System.out.println("m2"); <- or anything else that does not affect this.x
}
}+编辑,因为m1()只有y上的读-读关系,jit编译器可以通过将执行顺序更改为以下方式来优化m1()吗?它是否破坏了java模型的一致性?-edit
public void m1(int y){
m2(y);
this.x = y;
}如果可以对m1()进行优化,那么如果m2()在优化的代码中抛出一个异常,是否仍然会执行假象呢?
我不明白javase7规范,在这种情况下会发生什么?
oracle.com/javase/specs/jvms/se7 7
Java虚拟机可能允许在抛出异步异常之前执行少量但有限制的执行。允许这种延迟允许优化的代码检测和抛出这些异常,在符合Java编程语言语义的情况下处理它们是可行的。Java引发的异常是精确的:当发生控制传输时,在抛出异常之前执行的指令的所有效果都必须显示为发生了。在引发异常的点之后发生的指令似乎没有被计算过。如果优化的代码已经推测地执行了一些在异常发生点之后的指令,则这些代码必须准备好将这种推测性的执行隐藏在程序的用户可见状态下。
我理解回滚行为,但我不知道“未执行”指令会发生什么。从技术上讲,由于优化,做作没有被“执行”,这是否意味着它永远不会被执行?
发布于 2016-08-18 17:43:58
你正在拼凑两个概念,它们唯一的共同点就是你不理解它们。
重新排序是一种优化,绝不允许修改代码执行的结果。因此,提出诸如“JVM是否允许以破坏代码的方式重新排序?”这样的问题是过时的。当然不是。唯一可能的是,在没有适当的同步的情况下,结果可能以不同的顺序呈现给不同的线程。
另外,你应该问问自己为什么你认为
public void m1(int y){
m2(y);
this.x = y;
}是一种优化
public void m1(int y){
this.x = y;
m2(y);
}有什么改善?
您从规范中选择的另一件事是异步异常,这是一种只适用于两种情况的特殊情况。
-调用类线程或ThreadGroup的停止方法,或 - Java虚拟机实现中发生内部错误
这些显然是非常特殊的条件,应该很明显,不应该要求优化的代码不断地轮询这些条件。所述段落描述了这种例外可能被推迟的情况,但应当清楚的是,这些限制并没有解除其他现有的限制,即优化不可能改变执行的结果。
换句话说,查看孤立的指令并认为JVM没有什么更好的方法来处理它们。优化的一般规则是,它们不能改变可观察的效果,而且我们不能从孤立的代码段中判断应用程序中可以观察到什么。例如,如果变量x从未被读取,那么它可能永远不会被写入。甚至可能存在这样的情况:保存变量C的x实例从未创建过,因为不需要它来产生打印该消息的副作用。这一切都是你不会注意到的改变,…
https://stackoverflow.com/questions/38766478
复制相似问题