偏向锁、轻量级锁、重量级锁、自旋锁、自适应自旋锁

news2024/11/26 4:39:27

1. 偏向锁

偏向锁就是在运行过程中,对象的锁偏向某个线程。即在开启偏向锁机制的情况下,某个线程获得锁,当该线程下次再想要获得锁时,不需要重新申请获得锁(即忽略synchronized关键词),直接就可以执行同步代码,比较适合竞争较少的情况。

偏向锁的目标是,减少无竞争且只有一个线程使用锁的情况下,使用轻量级锁而产生的性能消耗。轻量级锁每次申请、释放锁都至少需要一次CAS,但偏向锁只有初始化时需要一次CAS。

如果明显存在其他线程申请锁,那么偏向锁将很快膨胀为轻量级锁。如果需要,使用参数-XX:-UseBiasedLocking禁止偏向锁优化(默认打开)。

1.1 偏向锁获取过程

  1. 查看Mark Word中偏向锁的标识以及锁标志位,若是否为偏向锁为1,并且锁标志位为01,则该锁为可偏向状态。
  2. 若该锁为可偏向状态,判断Mark Word中的线程ID与当前线程ID是否相等,如果相同,则直接执行同步代码,否则通过CAS操作竞争锁。
  3. 如果竞争成功,将Mark Word中线程ID设置为当前线程ID,然后执行同步代码。
  4. 如果竞争失败,说明有其他线程竞争。持有偏向锁状态的线程在没有字节码正在执行的情况下释放锁,然后恢复到未锁定状态或者膨胀为轻量级锁。

1.2 偏向锁释放过程

持有偏向锁的线程不会主动释放锁,只有遇到其他线程尝试竞争偏向锁时,持有偏向锁状态的线程才会释放锁。持有持有偏向锁的线程需要等到所有的同步任务执行完成之后(即没有字节码正在执行),才会暂停持有偏向锁的线程,然后恢复到未锁定状态或者膨胀为轻量级锁。

Mark Word是对象头的一部分,每个线程都拥有自己的线程栈(虚拟机栈),记录线程和函数调用的基本信息。

2. 轻量级锁

轻量级锁是相对于重量级锁而言的,使用时不需要申请互斥量。而是在没有多线程竞争的情况下,使用轻量级锁能够减少性能消耗,但是当多个线程同时竞争锁时,轻量级锁会膨胀为重量级锁。

轻量级锁的目标是,减少无实际竞争情况下,使用重量级锁产生的性能消耗,包括系统调用引起的内核态与用户态切换、线程阻塞造成的线程切换等。

1.1 轻量级锁获取过程

  1. 当线程执行代码进入同步块时,若Mark Word锁标识为无锁状态(是否为偏向锁为0,锁标志位为01),虚拟机会在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间(用于存储当前对象的Mark Word的拷贝,官方称之为Dispalced Mark Word)。
  2. 复制对象头中的Mark Word到锁记录中。
  3. 复制成功后,虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指针,并将Lock Record里的owner指针指向对象的Mark Word
  4. 如果更新成功,则这个线程拥有了这个锁,并将锁标志位设置00,此对象处于轻量级锁定状态。
  5. 如果更新失败,虚拟机会检查对象的Mark Word是否指向当前线程的栈帧。如果是,则说明当前线程已经拥有这个锁,可进入执行同步代码;如果不是,则说明多个线程竞争,轻量级锁就会膨胀为重量级锁,Mark Word中存储重量级锁(互斥锁)的指针,后面等待锁的线程也要进入阻塞状态。

1.2 轻量级锁释放过程

  • 通过CAS操作尝试把线程中复制的Displaced Mark Word对象替换当前的Mark Word。
  • 如果替换成功,整个同步过程就完成了。
  • 如果替换失败,说明有其他线程尝试过获取该锁(此时锁已膨胀),那就要在释放锁的同时,唤醒被挂起的线程。

3. 重量级锁

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

4. 自旋锁

在自旋状态下,当一个线程A尝试进入同步代码块,但是当前的锁已经被线程B占有时,线程A不进入阻塞状态,而是不停的空转,等待线程B释放锁。如果锁的线程能在很短时间内释放资源,那么等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞状态,只需自旋,等持有锁的线程释放后即可立即获取锁,避免了用户线程和内核的切换消耗。

优点:开启自旋锁后能减少线程的阻塞,在对于锁的竞争不激烈且占用锁时间很短的代码块来说,能提升很大的性能,在这种情况下自旋的消耗小于线程阻塞挂起的消耗。 缺点:在线程竞争锁激烈,或持有锁的线程需要长时间执行同步代码块的情况下,使用自旋会使得CPU做太多无用功。

JDK1.6中,设置参数-XX:+UseSpinning开启。JDK1.7后,由JVM自动控制。

5. 自适应自旋锁

自适应意味着自旋的时间不再固定了,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定:

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

自适应自旋解决的是“锁竞争时间不确定”的问题。JVM很难感知确切的锁竞争时间,而交给用户分析就违反了JVM的设计初衷。自适应自旋假定不同线程持有同一个锁对象的时间基本相当,竞争程度趋于稳定。因此,可以根据上一次自旋的时间与结果调整下一次自旋的时间。

6. 总结

锁类型

优点

缺点

适用场景

偏向锁

加锁和解锁不需要额外的消耗,和执行非同步方法比仅存在纳秒级的差距。

如果线程间存在锁竞争,会带来额外的锁撤销的消耗。

适用于只有一个线程访问同步块场景。

轻量级锁

竞争的线程不会阻塞,提高了程序的响应速度。

如果始终得不到锁竞争的线程使用自旋会消耗CPU。

追求响应时间。同步块执行速度非常快。

重量级锁

线程竞争不使用自旋,不会消耗CPU。

线程阻塞,响应时间缓慢。

追求吞吐量。同步块执行速度较长。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/643804.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python 房价数据可视化以数据缺失处理、及回归算法

基本信息概述 房价数据为他国地区使用工具为JupyterLab、python3用到的包 绘图包:seaborn、matplotlib数据处理包:numpy、pandas统计计算包:math、scipy回归模型包:make_pipeline、 RobustScaler、ElasticNet,Lasso、KernelRidge…

设计模式(十四):行为型之策略模式

设计模式系列文章 设计模式(一):创建型之单例模式 设计模式(二、三):创建型之工厂方法和抽象工厂模式 设计模式(四):创建型之原型模式 设计模式(五):创建型之建造者模式 设计模式(六):结构型之代理模式 设计模式…

Python使用最新版pyinstaller将项目或程序打包成exe或者mac中的可执行文件

1、pyinstaller的说明: pyinstaller 能够在 Windows、Linux、Mac 等操作系统下将 Python 源文件打包,通过对源文件打包, Python 程序可以在没有安装 Python 的环境中运行,也可以作为一个独立文件方便传递和管理。 PyInstaller 支…

进程管道:父进程和子进程

在接下来的对pipe调用的研究中,我们将学习如何在子进程中运行一个与其父进程完全不同的另外一个程序,而不是仅仅运行一个相同程序。我们用exec调用来完成这一工作。这里的一个难点是,通过exec调用的进程需要知道应该访问哪个文件描述符。在前…

设计模式(十三):行为型之模板方法模式

设计模式系列文章 设计模式(一):创建型之单例模式 设计模式(二、三):创建型之工厂方法和抽象工厂模式 设计模式(四):创建型之原型模式 设计模式(五):创建型之建造者模式 设计模式(六):结构型之代理模式 设计模式…

S200, S1700, S5700交换机忘记密码怎么办(huawei)

目录 交换机忘记密码怎么办?如何修改或清除密码? 简介 一:修改了所有默认密码,还忘记了所有密码 二:忘记了Console口登录密码 方法一:通过STelnet/Telnet登录设备修改Console口密码 方法二&#xff1…

RV1126笔记三十六:PaddleOCR环境搭建一

若该文为原创文章,转载请注明原文出处。 在前面测试过PaddleOCR的文字识别功能,现在自己搭建训练模型并测试。 这篇主要是环境搭建,环境为win10无GPU. 1、创建环境 # 创建paddle环境 conda create -n paddle python=3.8 # 查看环境 conda env list # 切换环境 conda acti…

第三章 模型篇:模型与模型的搭建

写在前面的话 这部分只解释代码,不对线性层(全连接层),卷积层等layer的原理进行解释。 尽量写的比较全了,但是自身水平有限,不太确定是否有遗漏重要的部分。 教程参考: https://pytorch.org/tutorials/ https://githu…

RK3588平台开发系列讲解(以太网篇)SGMII和RGMII接口特性

文章目录 一、MAC 与 PHY的连接二、MAC 与 PHY 在OSI 中位置2.1、网络层2.2、数据链路层2.3、物理层三、RGMII四、SGMII沉淀、分享、成长,让自己和他人都能有所收获!😄 一、MAC 与 PHY的连接 从硬件的角度看,以太网接口电路主要由MAC控制器和物理层PHY芯片两部分组成。 以…

Redis 五大数据类型/结构

Redis 五大数据类型/结构 操作文档 官方文档: https://redis.io/commands 中文文档: http://redisdoc.com/ Redis 数据存储格式 一句话: redis 自身是一个Map,其中所有的数据都是采用key : value 的形式存储 key 是字符串,value 是数据,数…

流媒体接入服务的一般模型

0x00 背景说明 媒体接入服务用来实现媒体资源(resource)的接收和发送,在有限范围内实现不同接入协议的转换。 0x01 一般模型 媒体传输通道的建立步骤通常分为两个阶段: 握手/协商媒体传输 其中,握手/协商操作通常包含: 媒体…

【GD32F303CCT6BlueBill开箱点灯教程】

【GD32F303CCT6BlueBill开箱点灯教程】 1. 搭建环境1.1 官方资料1.2 安装Keil 51.3 安装芯片选型插件pack包 2. 编译2.1 Keil4转换为Keil5工程2.2 选择芯片型号2.3 存储器类型2.4 选择下载器2.5 内存下载设置 3. 烧录3.1 Keil内烧录3.1.1 J-Link烧录3.1.2 ST-Link烧录3.1.3 CMS…

读书笔记:《远见:如何规划职业生涯3大阶段》

《远见:如何规划职业生涯3大阶段》,作者布赖恩. 费瑟斯通豪,豆瓣链接:https://book.douban.com/subject/27609489/ 主旨:描述职业生涯中3个截然不同但相互关联的阶段,教会我们如何不断储备职场燃…

【linux指南--命令大全】

系统的学习linux常用的命令,命令很全所以篇幅很长,可以作为你查阅命令的手册。也欢迎大佬们评论区补充。 文章目录 常见目录介绍配置文件系统操作帮助命令man 帮助help 帮助info 帮助 显示当前的目录名称文件查看建立目录删除空目录复制文件移动文件删除…

Qt下面窗口嵌套,嵌套窗口中包含:QGraphicsView、QGraphicsScene、QGraphicsIte

Qt系列文章目录 文章目录 Qt系列文章目录前言一、嵌套窗口二、注意事项 前言 我们有一个主窗口mainwindow,需要向其中放入新的界面,你可以自己定义里面内容。 Qt的嵌套布局由QDockWidget完成,用Qt Creator拖界面得到的dock布置形式比较固定,…

vmware设置centos客户机和windows宿主机共享文件夹

一、安装内核 kernel-devel 包 yum install gcc yum install kernel-devel-$(uname -r) 注意,如果自己修改过内核版本,需要确保 uname -r 显示的版本和实际使用的内核版本一致。 二、安装 vmware-tools 在vmware上点击菜单:虚拟机->安…

Android kotlin 实现仿京东多个item向左自动排队(横向、动手滑动、没有首尾滑动)功能

文章目录 一、实现效果二、引入依赖三、源码实现1、适配器2、视图实现一、实现效果 二、引入依赖 在app的build.gradle在添加以下代码 1、implementation com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6,这个里面带的适配器,直接调用就即可 BaseRecyclerViewAdapt…

【图神经网络】图神经网络(GNN)学习笔记:Graph Embedding

图神经网络(GNN)学习笔记:Graph Embedding 为什么要进行图嵌入Graph embedding?Graph Embedding使用图嵌入的优势有哪些?图嵌入的方法有哪些?节点嵌入方法(Node Embeddings)1. DeepWalk2. LINE…

CTFShow-WEB入门篇命令执行详细Wp(29-40)

WEB入门篇--命令执行详细Wp 命令执行:Web29:Web30:Web31:web32:web33:web34:web35:web36:web37:web38:web39:web40: CTFSh…

【哈希表part02】| 454.四数相加、383.赎金信、15.三数之和、18.四数之和

目录 ✿LeetCode454.四数相加❀ ✿LeetCode383.赎金信❀ ✿LeetCode15.三数之和❀ ✿LeetCode18.四数之和❀ ✿LeetCode454.四数相加❀ 链接:454.四数相加 给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多…