从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; }