synchronized和lock

16 篇文章 0 订阅

synchronized

synchronized用的锁是存在java对象头里的

JVM基于进入和退出Monitor对象来实现方法同步和代码块同步。

1.代码块同步

在这里插入图片描述
monitorenter指令是在编译后插入到同步代码块开始位置,而monitorexit是插入到方法结束后和异常处。
在执行monitorenter指令时,首先要去尝试获取锁,如果这个锁对象没有被占用 ,或者当前线程已经用了那个锁对象,那就把锁的计数器加1;相应的,在执行monitorexit指令时会将锁计数器减1,当计数器被减到0时,锁就释放了。如果获取锁失败了,那当前线程就要阻塞等待,直到锁对象被另一个线程释放。

2.同步方法

在这里插入图片描述
JVM就是根据该标示符来实现方法的同步的:当方法调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取monitor,获取成功之后才能执行方法体,方法执行完后再释放monitor。在方法执行期间,其他任何线程都无法再获得同一个monitor对象。 其实本质上没有区别,只是方法的同步是一种隐式的方式来实现,无需通过字节码来完成。

lock

lock锁使用的是CAS和volatile来实现同步的,CAS使用硬件命令实现缓存一致性保证了原子性,volatile保证了可见性,所线程环境下所有的线程通过CAS进行竞争资源,只能有一个成功,其它的都会自旋。

Lock的存储结构:一个int类型状态值(用于锁的状态变更),一个双向链表(用于存储等待中的线程)。

Lock获取锁的过程:本质上是通过CAS来获取状态值修改,如果当场没获取到,会将该线程放在线程等待链表中。

Lock释放锁的过程:修改状态值,调整等待链表。 Lock大量使用CAS+自旋。因此根据CAS特性,lock建议使用在低锁冲突的情况下。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值