当前位置:  开发笔记 > 编程语言 > 正文

为什么Java编译器在“同步块”之前添加“冗余读取”?

如何解决《为什么Java编译器在“同步块”之前添加“冗余读取”?》经验,为你挑选了1个好方法。



1> SubOptimal..:

从JLS 3.14开始

Java虚拟机中的同步是通过监视器的进入和退出来实现的,显式地(通过使用monitorenter和monitorexit指令)或隐式地(通过方法调用和返回指令)来实现。

为确保monitorexit始终执行,编译器为添加了一个隐式catch子句Throwable

为了在突然的方法调用完成时强制正确配对Monitorenter和MonitorExit 指令,编译器生成异常处理程序(第2.10节),该异常处理程序将匹配任何异常,并且其关联代码执行必要的MonitorExit指令。

使用时,javap -c Demo您可以在偏移量12-16处看到此附加字节码

 0: aload_0
 1: getfield      #3                  // Field lock:Ljava/lang/Object;
 4: dup
 5: astore_1
 6: monitorenter
 7: aload_1 
 8: monitorexit
 9: goto          17
12: astore_2
13: aload_1
14: monitorexit
15: aload_2
16: athrow
17: return
Exception table:
     from    to  target type
         7     9    12   any
        12    15    12   any

生成的代码为伪代码

Object var1 = this.lock;
try {
   monitorenter(var1);
   // more code here ...
   monitorexit(var1);
} catch (Throwable t) {
   monitorexit(var1);
   throw t;
}

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有