synchronized底层原理+锁升级

synchronized锁升级原理详解
一、底层原理
  1. 同步代码块:通过 monitorenter 和 monitorexit 两条字节码指令来实现,本质是获取对象的 Monitor(监视器锁)
  2. 同步方法:通过方法上的 ACC_SYNCHRONIZED 访问标志来标识,当方法被调用时,调用指令会检查该标志,然后自动执行加锁和解锁的过程,该过程同样基于Monitor
二、Monitor

Monitor 是线程私有的数据结构,每一个java对象潜在的与一个Monitor相关联,在java对象头中存在一个指向Monitor的指针。

Monitor 主要包含的组件:

  1. owner:指向持有该monitor的线程,初始时为null
  2. entryList:处理 BLOCKED 阻塞状态的线程,正在等待锁释放,以竞争所有权
  3. waitSet:处于 Waiting 状态的线程,这些线程执行了 object.wait() 方法,等待被 notify() / notifyAll() 唤醒

工作流程:

  1. 线程执行到 monitorenter 指令时,会尝试占用该对象的 Monitor
  2. 如果 owner 为null,当前线程成为 owner,并将计数器置为1
  3. 如果当前线程已经是 owner,且是可重入锁,则重入此锁,计数器加1
  4. 如果 owner 是其它的线程,当前线程进入到 entryList 中,变成 BLOCKED 状态
  5. 持有 Monitor 的线程执行完同步代码块后,会执行 monitorexit 指令,将计数器减1。当计数器减为0时,线程释放 Monitor,并唤醒 entryList 中等待的线程来重新竞争锁

Monitor机制是依赖于操作系统的 Mutex Lock 互斥锁来实现的,涉及到用户态到内核态的切换,进程需要切换上下文,成本非常高,所以 synchronized 是一个重量级锁。

三、锁升级

为减少获取锁和释放锁带来的性能消耗,synchronized 的锁是不断升级的,而不是一开始就是重量级锁,锁只能升级不能降级。锁的级别从低到高为:
无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁

升级过程:
无竞争时,使用偏向锁,该线程后续进入和退出同步块时,发现记录的偏向的线程id是自身,则直接进入。当发现有其它线程来竞争锁时,偏向锁撤销,升级为轻量级锁;
轻量级锁时,通过CAS自旋来加锁和解锁,避免线程阻塞。CAS操作失败且之前加锁的不是自身,说明有多个线程在竞争。未获取到锁的线程在自旋期间(不是一次失败立马升级),一直获取不到锁,这时候会升级为重量级锁,也就是Monitor机制

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的Coder*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值