Java 锁机制

当没有竞争的时候,系统会默认使用偏斜锁。JVM 利用CAS(compare and swap)在 对象头的第一部分(mark word)设置 偏向线程ID,表示对象偏向于这个线程。 因为大部分并发场景下面 对象 生命周期 中最多被一个线程锁定, 使用偏斜锁的话可以降低 低竞争状态下的 额外开销。

这个时候如果有另外的线程试图锁定已经被倾斜过的对象,JVM会撤销(revoke)偏斜锁, 并切换到轻量级锁。 这时候轻量级锁 会根据 CAS 操作 Mark word 来试图 获取锁,如果成功就 切换为轻量级锁;否则 进一步 升级 为重量级锁。

 

自旋锁: 是竞争失败的线程,并不会真实的在操作系统层面挂起等待,而是JVM会让线程做几次空循环(For (;;)),循环几轮后,如果可以获得锁,那么进入临界区,如果还是不能获得锁的话,这时候才会在操作系统挂起等待。 一般在 低竞争并且占用锁的时间短的线程很实用。是一种在悲观锁中的乐观优化(因为JVM的synchronized是一种悲观锁 )。

 

死锁: 因为悲观锁独占CPU的特性,死锁就是线程A在持有锁A的情况下,试图进入锁B; 而线程B 在持有 锁B的情况下,试图进入锁A。如下图:

例如多个嵌套的 synchronized 有可能会发生死锁的情况。 所以为了避免死锁, 我们就需要 注意锁的获取顺序。 或者使用Object.wait() 或者  CountDownLatch.await()等带超时的方法。在长时间没有锁的情况下,即退出逻辑。

另外如果发生死锁的情况下可以使用jstack等工具去获取死锁发生的位置,这里就不过多阐述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值