java中的锁——偏向锁 / 轻量级锁 / 重量级锁

【笔记】java中的所有锁


锁的状态总共有四种:无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁(但是锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级)。锁的状态是通过对象监视器在对象头中的字段来表明的。JDK 1.6中默认是开启偏向锁和轻量级锁的。

  • 锁膨胀:从轻量锁膨胀到重量级锁是在轻量级锁解锁过程发生的。
    四种状态会随着竞争的情况逐渐升级,而且是不可逆的过程,即不可降级。
1.无锁状态
2.偏向锁状态
3.轻量级锁状态
4.重量级锁状态

偏向锁

偏向锁:一段同步代码一直被一个线程所访问,那么该线程会自动获取锁。降低获取锁的代价。
如果需要,使用参数-XX:-UseBiasedLocking禁止偏向锁优化(默认打开)

轻量级

轻量级锁:当锁是偏向锁的时候,被另一个线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,提高性能

“轻量级”是相对于使用操作系统互斥量来实现的传统锁而言的。但是,轻量级锁并不代替重量级锁的,其本意是在没有多线程竞争的前提下,减少传统的重量级锁使用产生的性能消耗。
在解释轻量级锁的执行过程之前,先明白一点,轻量级锁所适应的场景是线程交替执行同步块的情况,如果存在同一时间访问同一锁的情况,就会导致轻量级锁膨胀为重量级锁。

重量级锁

重量级锁:当锁为轻量级锁的时候,另一个线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数的时候,还没有获取到锁,就会进入阻塞,该锁膨胀为重量级锁。重量级锁会让其他申请的线程进入阻塞,性能降低。

  • 锁的升级过程:
    一旦对象锁升级为重级锁后,后续线程对该对象的操作都将是加锁为重量级锁
  • 锁不存在降级:
    锁只有从偏向锁->轻量级/重量级 或者 直接 轻量级-> 重量级. 不会降级,只有解锁
    在这里插入图片描述
    重量级锁是通过monitor实现的,锁的标志位为10,对象头中的指针指向monitor对象的起始地址。在java虚拟机中,monitor是由ObjectMonitor实现。位于\openjdk-jdk8u-jdk8u\openjdk-jdk8u-jdk8u\hotspot\src\share\vm\runtime包中。

Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的。但是监视器锁本质又是依赖于底层的操作系统的Mutex Lock来实现的。而操作系统实现线程之间的切换这就需要从用户态转换到核心态,这个成本非常高,状态之间的转换需要相对比较长的时间,这就是为什么Synchronized效率低的原因。因此,这种依赖于操作系统Mutex Lock所实现的锁我们称之为“重量级锁”。


java中的1.公平锁 / 非公平锁

java中的2.可重入锁 / 不可重入锁

java中的3.独享锁 / 共享锁/AOS

java中的4.互斥锁 / 读写锁

java中的5.乐观锁 / 悲观锁

java中的6.分段锁

java中的7.偏向锁 / 轻量级锁 / 重量级锁

java中的8.自旋锁

发布了50 篇原创文章 · 获赞 13 · 访问量 2402

猜你喜欢

转载自blog.csdn.net/endless_Y/article/details/104969803