首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >锁原理:偏向锁、轻量锁、重量锁1.加锁2.撤销偏向锁1.加锁2.解锁3.膨胀为重量级锁

锁原理:偏向锁、轻量锁、重量锁1.加锁2.撤销偏向锁1.加锁2.解锁3.膨胀为重量级锁

作者头像
用户1174983
发布2018-02-05 15:42:46
3.5K0
发布2018-02-05 15:42:46
举报
文章被收录于专栏:钟绍威的专栏钟绍威的专栏

 java中每个对象都可作为锁,锁有四种级别,按照量级从轻到重分为:无锁、偏向锁、轻量级锁、重量级锁。每个对象一开始都是无锁的,随着线程间争夺锁,越激烈,锁的级别越高,并且锁只能升级不能降级。

一、java对象头

 锁的实现机制与java对象头息息相关,锁的所有信息,都记录在java的对象头中。用2字(32位JVM中1字=32bit=4baye)存储对象头,如果是数组类型使用3字存储(还需存储数组长度)。对象头中记录了hash值、GC年龄、锁的状态、线程拥有者、类元数据的指针。

Java对象头的结构
Java对象头的结构
在不同锁状态下Mark Word的结构(32位下)
在不同锁状态下Mark Word的结构(32位下)

二、偏向锁

 在实际应用运行过程中发现,“锁总是同一个线程持有,很少发生竞争”,也就是说锁总是被第一个占用他的线程拥有,这个线程就是锁的偏向线程。

 那么只需要在锁第一次被拥有的时候,记录下偏向线程ID。这样偏向线程就一直持有着锁,直到竞争发生才释放锁。以后每次同步,检查锁的偏向线程ID与当前线程ID是否一致,如果一致直接进入同步,退出同步也,无需每次加锁解锁都去CAS更新对象头,如果不一致意味着发生了竞争,锁已经不是总是偏向于同一个线程了,这时候需要锁膨胀为轻量级锁,才能保证线程间公平竞争锁。

1.加锁

偏向锁加锁发生在偏向线程第一次进入同步块时,CAS原子操作尝试更新对象的Mark Word(偏向锁标志位为"1",记录偏向线程的ID)。

2.撤销偏向锁

 当有另一个线程来竞争锁的时候,就不能再使用偏向锁了,要膨胀为轻量级锁。 竞争线程尝试CAS更新对象头失败,会等待到全局安全点(此时不会执行任何代码)撤销偏向锁。

撤销偏向锁的过程
撤销偏向锁的过程
撤销偏向锁的过程
撤销偏向锁的过程

三、轻量级锁

 轻量锁与偏向锁不同的是:

  1. 轻量级锁每次退出同步块都需要释放锁,而偏向锁是在竞争发生时才释放锁
  2. 每次进入退出同步块都需要CAS更新对象头
  3. 争夺轻量级锁失败时,自旋尝试抢占锁

 可以看到轻量锁适合在竞争情况下使用,其自旋锁可以保证响应速度快,但自旋操作会占用CPU,所以一些计算时间长的操作不适合使用轻量级锁。

1.加锁

 加锁过程和偏向锁加锁差不多,也是CAS修改对象头,只是修改的内容不同。

  1. 在MarkWord中保存当前线程的指针
  2. 修改锁标识位为“00”

采用CAS操作的原因是,不想在加锁解锁上再加同步

 如果对象处于无锁状态(偏向锁标志位为"0",锁标志位为"01"),会在线程的栈中开辟个锁记录空间(Lock Record),将Mark Word拷贝一份到Lock Record中,称为Displaced Mark Word,在Lock Record中保存对象头的指针(owner)。 接下来CAS更新MarkWord,将MarkWord指向当前线程,owner指向MarkWord,如果失败了,则意味着出现了另一个线程竞争锁,此时需要锁膨胀为轻量级锁。

CAS操作前的栈和MarkWord状态
CAS操作前的栈和MarkWord状态
CAS操作后的栈和MarkWord状态
CAS操作后的栈和MarkWord状态

2.解锁

 用CAS操作锁置为无锁状态(偏向锁位为"0",锁标识位为"01"),若CAS操作失败则是出现了竞争,锁已膨胀为重量级锁了,此时需要释放锁(持有重量级锁线程的指针位为"0",锁标识位为"10")并唤醒重量锁的线程。

3.膨胀为重量级锁

 当竞争线程尝试占用轻量级锁失败多次之后,轻量级锁就会膨胀为重量级锁,重量级线程指针指向竞争线程,竞争线程也会阻塞,等待轻量级线程释放锁后唤醒他。

膨胀为重量级锁
膨胀为重量级锁

三、重量级锁

 重量级锁的加锁、解锁过程和轻量级锁差不多,区别是:竞争失败后,线程阻塞,释放锁后,唤醒阻塞的线程,不使用自旋锁,不会那么消耗CPU,所以重量级锁适合用在同步块执行时间长的情况下。

四、参考

  1. 《Java并发编程的艺术》
  2. 《轻量级锁与偏向锁》
  3. 《Synchronized下的三种锁:偏向锁 轻量锁 重量锁 理解》
  4. 《JAVA锁的膨胀过程和优化》
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-12-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、java对象头
  • 二、偏向锁
    • 1.加锁
      • 2.撤销偏向锁
      • 三、轻量级锁
        • 1.加锁
          • 2.解锁
            • 3.膨胀为重量级锁
            • 三、重量级锁
            • 四、参考
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档