java代码块如果出现异常_synchronized 语句块里代码出现异常会怎么样?

前几天同组的一个小伙伴忽然问我一个问题:synchronized 里异常挂掉会怎么样,锁释放不释放,为什么?我当时的本能回答是:锁肯定会释放,不释放就出问题了,应该会在异常退出时自动释放掉。但至于为什么,却也想不起来了,于是重新翻看了下《深入理解 Java 虚拟机》, 找到了答案。

先介绍 Java 虚拟机的两个关于同步的指令

字节码

助记符

指令含义

0xc2

monitorenter

获得对象的锁,用于同步方法或同步块

0xc3

monitorexit

释放对象的锁,用于同步方法或同步块

下面举个例子说明一下:

public class Test {

void onlyMe(Foo f) {

synchronized(f) {

doSomething();

}

}

void doSomething() {}

private static class Foo {

}

}

经 javac 编译后,这段代码生成的字节码序列如下(仅仅截取了 onlyMe 方法):

20170610201716_960.png

通过上面可以看到有两个 monitorexit 指令,第一个 monitorexit 指令如果正确执行,会走到下面的 goto 指令,直接跳转到 18 行 return,而如果发生异常,下面的 astore_3 和 aload_2 指令会继续执行异常问题, aload_2 将把局部变量 Slow 2 的元素 (即 f ) 入栈,下一步会继续执行 monitorexit 指令退出同步。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值