文章目录

  • 1. 轻量级锁的核心原理
  • 2. 代码演示
  • 3. 轻量级锁的分类
  • 4. 轻量级锁的膨胀

1. 轻量级锁的核心原理

轻量级锁的执行过程:在抢锁线程进入临界区之前,如果内置锁(临界区的同步对象)没有被锁定,JVM首先将在抢锁线程的栈帧中建立一个锁记录(LockRecord),用于存储对象目前Mark Word的拷贝,然后抢锁线程将使用CAS自旋操作,尝试将内置锁对象头的Mark Word的ptr_to_lock_record(锁记录指针)更新为抢锁线程栈帧中锁记录的地址

如果抢锁成功,线程就拥有了这个对象锁。然后JVM将Mark Word中的lock标记位改为00(轻量级锁标志),即表示该对象处于轻量级锁状态。JVM会将Mark Word中原来的锁对象信息(如哈希码等)保存在抢锁线程锁记录的Displaced Mark Word(可以理解为放错地方的Mark Word)字段中,再将抢锁线程中锁记录的owner指针指向锁对象

为什么复制对象头的部分信息到线程堆栈中的锁记录的Displaced Mark Word字段?
因为内置锁对象的Mark Word的结构会有所变化,Mark Word将会出现一个指向锁记录的指针,而不再存着无锁状态下的锁对象哈希码等信息,所以必须将这些信息暂存起来,供后面在锁释放时使用。


2. 代码演示

package innerlock;import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;public class InnerLockTest {int a=1;double b=1.1;public static void main(String[] args) throws InterruptedException {System.out.println(VM.current().details());Object obj=new Object();new Thread(()->{synchronized (obj) {System.out.println("t1:"+ClassLayout.parseInstance(obj).toPrintable());}try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}},"t1").start();Thread.sleep(1000);//保证t1已经离开临界区new Thread(()->{synchronized (obj) {System.out.println("t2:"+ClassLayout.parseInstance(obj).toPrintable());}},"t2").start();}
}


上面的代码创建了两个线程,第一个线程t1获取到锁时无线程争夺资源,因此是偏向锁;当第二个线程去争夺t1持有的锁对象时,变成轻量级锁

轻量级锁的使用场景:如果一个对象虽然有多线程要加锁,但加锁的时间是错开的(也就是没有竞争),那么可以使用轻量级锁来优化。(比如上面代码,先是线程1进行加锁变成偏向锁,然后是线程2来抢占,此时线程1已经离开临界区)


3. 轻量级锁的分类

1. 普通自旋锁
当有线程来竞争锁时,抢锁线程会在原地循环等待,而不是被阻塞,直到那个占有锁的线程释放锁之后,这个抢锁线程才可以获得锁。
自旋会消耗CPU,因此不可能无休止地进行自旋,默认情况下,自旋的次数为10次,用户可以通过-XX:PreBlockSpin选项来进行更改。

2. 自适应自旋锁

等待线程空循环的自旋次数并非是固定的,而是会动态地根据实际情况来改变自旋等待的次数

  • 如果抢锁线程在同一个锁对象上之前成功获得过锁,JVM就会认为这次自旋很有可能再次成功,因此允许自旋等待持续相对更长的时间
  • 如果对于某个锁,抢锁线程很少成功获得过,那么JVM将可能减少自旋时间甚至省略自旋过程,以避免浪费处理器资源

4. 轻量级锁的膨胀

轻量级锁的优点:在多线程竞争不激烈的情况下,通过CAS机制竞争锁减少重量级锁产生的性能损耗。重量级锁使用了操作系统底层的互斥锁(MutexLock),会导致线程在用户态和核心态之间频繁切换,从而带来较大的性能损耗
轻量级锁的缺点:临界区代码执行耗时较长,在其执行期间,其他线程都在原地自旋等待,会空消耗CPU。因此,如果竞争这个同步锁的线程很多,就会有多个线程在原地等待继续空循环消耗CPU(空自旋),这会带来很大的性能损耗

在争用激烈的场景下,轻量级锁会膨胀为基于操作系统内核互斥锁实现的重量级锁


参考:《Java高并发编程卷2》 尼恩

轻量级锁的原理与实战相关推荐

  1. 轻量级锁_并发编程实战05:锁的状态

    无锁.偏向锁 .轻量级锁和重量级锁这四种锁是指锁的状态,专门针对synchronized的.在介绍这四种锁状态之前还需要介绍一些额外的知识. 首先为什么Synchronized能实现线程同步?在回答这 ...

  2. 重量级锁的原理与实战

    文章目录 1. 重量级锁的核心原理 2. 重量级锁的开销 3. 代码实例 4. 偏向锁.轻量级锁与重量级锁的对比 1. 重量级锁的核心原理 JVM中每个对象都会有一个监视器,监视器和对象一起创建.销毁 ...

  3. 通过实现网站访问计数器带你理解 轻量级锁CAS原理,还学不会算我输!!!

    精彩推荐 一百期Java面试题汇总 SpringBoot内容聚合 IntelliJ IDEA内容聚合 Mybatis内容聚合 一.实现网站访问计数器 1.线程不安全的做法 1.1.代码 package ...

  4. java代码轻量级锁_Java轻量级锁原理详解(Lightweight Locking)

    转自http://www.cnblogs.com/redcreen/archive/2011/03/29/1998801.html 大家知道,Java的多线程安全是基于Lock机制实现的,而Lock的 ...

  5. Java 轻量级锁原理详解(Lightweight Locking)

    2019独角兽企业重金招聘Python工程师标准>>> 大家知道,Java的多线程安全是基于Lock机制实现的,而Lock的性能往往不如人意. 原因是,monitorenter与mo ...

  6. synchronized锁升级之轻量级锁

    目录 一.什么是轻量级锁? 二.为什么引入轻量级锁? 三.轻量级锁的升级时机 四.轻量级锁的演示 五.轻量级锁的原理 六.轻量级锁升级为重量级锁的流程 七.轻量级锁的优缺点 一.什么是轻量级锁? 轻量 ...

  7. Java Synchronized 偏向锁/轻量级锁/重量级锁的演变过程

    前言 线程并发系列文章: Java 线程基础 Java 线程状态 Java "优雅"地中断线程-实践篇 Java "优雅"地中断线程-原理篇 真正理解Java ...

  8. 偏向锁,轻量级锁,重量级锁的核心原理

    前言:大家好,我是小威,24届毕业生,在一家满意的公司实习.本篇文章是关于并发编程中偏向锁,轻量级锁,重量级锁的核心原理知识记录. 本篇文章记录的基础知识,适合在学Java的小白,也适合复习中,面试中 ...

  9. 12.synchronized的锁重入、锁消除、锁升级原理?无锁、偏向锁、轻量级锁、自旋、重量级锁

    小陈:呼叫老王...... 老王:来了来了,小陈你准备好了吗?今天我们来讲synchronized的锁重入.锁优化.和锁升级的原理 小陈:早就准备好了,我现在都等不及了 老王:那就好,那我们废话不多说 ...

  10. Synchronized的原理及自旋锁,偏向锁,轻量级锁,重量级锁的区别

    在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,Java S ...

最新文章

  1. OpenCV寻找复杂背景下物体的轮廓
  2. 老板的亲戚给我当助手?
  3. 三种方式搭建yum源
  4. 浏览器如何生成URL
  5. 使用tkinter模块在Python中进行GUI编程
  6. check_mysql 脚本_如何使用myisamchk和mysqlcheck工具快速修复损坏的MySQL数据库文件
  7. Rust: rev()、Vec、其它
  8. java带参数的方法笔记_Java学习笔记十一:Java中的方法
  9. Alex Fung魔方解法学习记
  10. 瀚高DB兼容MySQL if函数
  11. 固定定位(fixed)和粘性定位(sticky)的比较
  12. OpenGL多重纹理使用与理解
  13. HDMI+VGA+USB3.0+PD3.0四合一多功能扩展坞|type c 扩展坞接口功能说明
  14. ORCID以及ResearcherID注册
  15. Tableau文件管理
  16. 计算机如何删除已连接的打印机驱动程序,怎么删除网上共享的打印机驱动程序...
  17. 网络视频的防盗与破解
  18. 2022最新HTML生成国庆头像网页源码+打开即用
  19. 2021_lg_03.SQL实战:如何用sql计算用户留存问题
  20. 利用腾讯云函数服务进行每日wps签到打卡(部分失效)

热门文章

  1. 8. 求 s=a+aa+aaa+aaaa+aa…a 的值
  2. 关于memset函数和赋值0x3f,2021-5-5
  3. 物流app开发需要多少钱
  4. ElasticSearch索引模板(template)操作:创建、查询、修改、删除
  5. java 时间换算_时间换算java实现
  6. 软件c#语言调用摄像头,C#中如何使用AForge实现摄像头录像功能
  7. ISP Pipeline
  8. linux服务器硬盘检测,Linux服务器硬盘坏道检测
  9. linux 磁盘隔离,Linux 磁盘坏道故障修复
  10. 百度地图api之路线规划