synchronize的实现原理和锁升级

synchronize存在着无锁、偏向锁、轻量级锁和重量级锁四种状态,会随着竞争的激烈逐渐升级。

偏向锁:
顾名思义,就是偏向第一个获得该对象的锁的线程,当线程请求到锁对象后,将锁对象的偏向标志改为1。然后使用CAS操作将线程的ID记录在锁对象的Mark Word中。以后该线程可以直接进入同步块,进去以后标志计数加一。但是,一旦有第二条线程需要竞争锁,那么偏向模式立即结束,进入轻量级锁的状态。

轻量级锁:
升级为轻量级锁以后,线程进入同步块的时候,就会在线程的栈帧创建一个Lock Record,并把锁对象的mark word拷贝进去,然后JVM使用CAS操作尝试将Mark Word更新为指向Lock Record的指针(对象标志位为00),如果更新成功代表获取锁成功就执行同步操作。更新失败就一直自旋,超过10次以后就变成重量级锁,所有未获得锁的线程都阻塞队列等待。
轻量级锁解锁时,会使用CAS将之前复制在栈桢中的 Displaced Mard Word 替换回 Mark Word 中。如果替换成功,则说明整个过程都成功执行,期间没有其他线程访问同步代码块。

重量级锁:
重量级锁是互斥锁,存在着一个从用户态到核心态的切换,很浪费时间。
同步代码块:
是通过monitorenter和monitorexit来实现的,它会在同步代码块的前后加上这两个指令,线程执行monitorenter指令代表该锁(就是和对象关联的monitor)被该对象持有,执行完同步代码块以后就会唤醒阻塞的线程。
同步方法:
它实现在方法调用和返回操作之中。JVM可以从方法常量池中的方法表结构(method_info Structure) 中的 ACC_SYNCHRONIZED 访问标志区分一个方法是否同步方法。当方法调用时,将会 检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先持有monitor,然后再执行方法,最后在方法完成时释放monitor。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值