内建锁(Synchronized)的优化

JDK1.6后,内建锁被优化为三种锁:
  --无锁状态:最初没有任何线程尝试获取锁。
  偏向锁:认为从始至终只有一个线程在竞争同一把锁。(最乐观)只在第一次请求锁时采用CAS操作。
  轻量级锁:多个线程在不同时间段请求同一把锁,(基本不存在锁竞争)。每次进入同步块时都会进行CAS操作。可以避免线程的阻塞及唤醒。
  重量级锁:悲观锁,即为JDK1.5以前的内建锁,会阻塞,唤醒请求加锁的线程,针对多线程在同一时刻竞争同一把锁,当线程获取到对象锁后,将其他参与竞争的线程阻塞。JVM会采用自适应自旋避免在非常小的同步块时阻塞线程。
1.无锁状态:对象头中的锁标志位为无锁,即:
是否为偏向锁:0
锁标志位:01
2.偏向锁:对象头中锁标志位为偏向锁,即:
是否为偏向锁:1
锁标志位:01
//1,2中,是否为偏向锁就是无锁和偏向锁的区别
3.轻量级锁:00
4.重量级锁: 10
5.GC标记:11

内建锁的升级过程:
无锁状态升级为偏向锁及偏向锁的运行:
  最初对象锁是无锁状态,当有一个线程希望拿到对象锁时,首先会检查对象头中的Mark Word,其中存储的线程ID是否与自己的线程ID相同,因为刚开始,Mark Word存储的线程ID一定为null,与当前线程ID一定不同,所以会继续判断Mark Word:是否为偏向锁,此时偏向锁标志为0,说明当前为无锁状态,此时会将当前线程的ID写入Mark Word中,并将是否为偏向锁标志置为1,线程进入代码块中运行。若偏向锁标志位为1,则不断尝试CAS操作争夺锁,或者在全局安全点时将偏向锁撤销,升级为轻量级锁。
在尝试CAS竞争锁时,新线程首先会暂停原来线程的运行,将Mark Word中线程ID置空,然后新老线程对对象锁进行争夺,当Mark Word中线程ID被置空次数超过一定限度后,JVM会认为偏向锁已经不适合当前对象锁,此时,偏向锁升级为轻量级锁。
  (图中最下方方框中“获”字,打错了,应该是“或”。//手动笑哭脸)
无锁到偏向锁
  偏向锁运行流程及竞争后膨胀:
在这里插入图片描述
重量级锁的运行及竞争:
  重量级锁会阻塞竞争锁失败的线程,并在在锁释放时唤醒这些被阻塞的线程。
自适应自旋
  根据上一次自旋是否得到锁决定下一次自旋时间的长短,当第一次成功获得到锁,JVM希望在第二次还继续可以得到锁,就会增加自旋的时间,提升再次得到锁的概率;而当第一次竞争没有得到锁,JVM第二次也不会报太大希望,就会减少下次自旋时间。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值