synchronized锁升级的过程

synchronized锁升级的过程

synchronized给同步资源加的锁就在Java对象头里;Hotspot的对象头主要包括两部分数据:Mark Word**(标记字段)、**class Pointer(类型指针)。

Mark Word:大小=xx位(JVM)bit,默认存储对象的HashCode分代年龄锁标志位信息。

锁状态 存储内容 标志位
无锁 对象的hashCode、对象分代年龄、是否是偏向锁(0) 01
偏向锁 偏向线程ID、偏向时间戳、对象分代年龄、是否是偏向锁(1) 01
轻量级锁 指向栈中锁记录的指针 00
重量级锁 指向互斥量(重量级锁)的指针 10

class Pointer:数组类型对象的大小=2*xx位(JVM)bit,非数组类型对象的大小=xx位(JVM)bit,对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例

synchronized 有4种锁的状态,这几个状态会随着竞争情况逐渐升级,锁状态只能升级不能降级

无锁:无锁没有对资源进行锁定,所有的线程都能访问并修改同一个资源,但同时只有一个线程能修改成功。(CAS原理应用即是无锁的实现 )

  • 解决问题:无锁无法全面代替有锁,但无锁在某些场合下的性能是非常高的
  • 何时升级为无锁:
  • 如何升级为无锁:

偏向锁:偏向锁是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁,降低获取锁的代价。

  • 解决问题:在只有一个线程执行同步代码块时能够提高性能
  • 何时升级为偏向锁:当一个线程访问同步代码块并获取锁时
  • 如何升级为偏向锁:在Mark Word里存储锁偏向的线程ID。在线程进入和退出同步块时不再通过CAS操作
  • 加锁和解锁:检测Mark Word里是否存储着指向当前线程的偏向锁

​ (偏向锁只需要在置换ThreadID的时候依赖一次CAS原子指令即可 )

轻量级锁:简单地将对象头部作为指针,指向持有锁的线程堆栈的内部,来判断一个线程是否持有对象锁

  • 解决问题:偏向锁升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能
  • 何时升级升级为轻量级锁:当锁是偏向锁的时候,被另外的线程所访问,偏向锁就会升级为轻量级锁
  • 如何升级为轻量级锁:

重量级锁

  • 解决问题:共享资源时确保线程安全
  • 何时升级为重量级锁:一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁升级为重量级锁。
  • 如何升级为重量级锁:

综上,偏向锁通过对比Mark Word解决加锁问题,避免执行CAS操作

轻量级锁是通过用CAS操作和自旋来解决加锁问题,避免线程阻塞和唤醒而影响性能。

重量级锁将除了拥有锁的线程以外的线程都阻塞

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0LGG9N6Y-1571281513504)(D:\weixinobU7Vjs0UlDpUbXEpi4j3BBnesQQ\c199b46244b34bffb1d2876d645e952b\clipboard.png)]

偏向锁就是在无竞争的情况下把整个同步都消除掉,连CAS都不做了。

锁对象第一次被线程获取时,虚拟机将对象头的标志位设位“01”,即偏向模式。同时使用CAS操作把获取到这个锁的线程的ID记录在对象的Mark word,如果CAS操作成功,持有偏向锁的线程每次进入到这个锁相关的同步块的时候,虚拟机不再进行任何同步操作。

当有另外一个线程获取这个锁时,偏向模式结束。根据锁对象目前是否处于被锁定状态,撤销偏向恢复到未锁定或轻量级锁定状态【如果线程到达安全点之后锁车厢结束,但是线程还在同步块中将会编程轻量级锁,否则变为无锁】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X0NSXGmv-1571281513505)(D:\weixinobU7Vjs0UlDpUbXEpi4j3BBnesQQ\0084972a50ca4e2faa5e503ebd184be8\clipboard.png)]

代码进入到同步块的时候,如果此对象没有锁定,虚拟机首先在当前线程的栈帧中建立一个锁记录空间(Lock Record),用于存储对象目前的Mark Word 的拷贝

然后使用CAS尝试将对象头的Mark Word 更新为指向Lock Record 的指针。如果更新成功,那么这个线程就拥有了该对象的锁,并且对象Mark word 的锁标志位转变为“00”。

如果更新失败,虚拟机首先检查对象的Mark Word 是否指向当前线程的栈帧,当指向,直接进入同步块执行,否则说明被其他线程抢占了,进行自旋等待

当有第三个线程争用同一个锁时,轻量级锁膨胀为重量级锁,锁标志位变为“10”,Mark word 存储的是指向重量级锁的指针,后面等待锁的线程进入阻塞状态

轻量级锁是在无竞争的情况下使用CAS操作去消除同步使用的互斥量。

的是指向重量级锁的指针,后面等待锁的线程进入阻塞状态

轻量级锁是在无竞争的情况下使用CAS操作去消除同步使用的互斥量。

你可能感兴趣的:(并发)