Synchronized 同步锁实现原理

通常 Synchronized 实现同步锁的方式有两种,一种是修饰方法,一种是修饰方法块。

通过反编译看下具体字节码的实现,运行以下反编译命令,就可以输出我们想要的字节码:

javap -v SyncTest.class // 再通过 javap 打印出字节文件

通过输出的字节码,你会发现:Synchronized 在修饰同步代码块时,是由 monitorenter 和 monitorexit
指令来实现同步的。进入 monitorenter 指令后,线程将持有 Monitor 对 象,退出 monitorenter
指令后,线程将释放该 Monitor 对象。

当 Synchronized 修饰同步方法时,并没有发现 monitorenter 和 monitorexit 指令,而是出现了一个
ACC_SYNCHRONIZED 标志。

这是因为 JVM 使用了 ACC_SYNCHRONIZED 访问标志来区分一个方法是否是同步方法。

当方法调用时,调用指令将会检查该方法是否被设置 ACC_SYNCHRONIZED 访问标志。

如果设置了该标志,执行线程将先持有 Monitor 对象,然后再执行方法。在该方法运行期间,其它线程将无法获取到该 Mointor
对象,当方法执行完成后,再释放该 Monitor 对象。

JVM 中的同步是基于进入和退出管程(Monitor)对象实现的。每个对象实例都会有一个Monitor,Monitor
可以和对象一起创建、销毁。Monitor 是由 ObjectMonitor 实现

当多个线程同时访问一段同步代码时,多个线程会先被存放在 EntryList 集合中,处于block
状态的线程,都会被加入到该列表。接下来当线程获取到对象的 Monitor 时,Monitor 是依靠底层操作系统的 Mutex Lock
来实现互斥的,线程申请 Mutex 成功,则持有该 Mutex,其它线程将无法获取到该 Mutex。

如果线程调用 wait() 方法,就会释放当前持有的 Mutex,并且该线程会进入 WaitSet
集合中,等待下一次被唤醒。如果当前线程顺利执行完方法,也将释放 Mutex。

同步锁在这种实现方式中,因 Monitor 是依赖于底层的操作系统实现,存在用户态与内核态之间的切换,所以增加了性能开销。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值