一篇文章说清 :无锁、偏向锁、轻量级锁、重量级锁

2023-05-16

文章目录

  • 前言
  • 一、无锁
  • 二、偏向锁
  • 三、轻量级锁(自选锁)
  • 四、重量级锁
    • 锁升级场景


前言

JDK1.6为了减少获得锁和释放锁所带来的性能消耗,引入了“偏向锁”和“轻量级锁”,所以在JDK1.6里锁一共有四种状态,无锁状态,偏向锁状态,轻量级锁状态和重量级锁状态,它会随着竞争情况逐渐升级。锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁。这种锁升级却不能降级的策略,目的是为了提高获得锁和释放锁的效率.

Java中的锁有几种状态:无锁 → 偏向锁 → 轻量级锁 → 重量级锁
在这里插入图片描述

一、无锁

偏向锁,顾名思义,它会偏向于第一个访问锁的线程

程序不会有锁的竞争。那么这种情况我们不需要加锁,所以这种情况下对象锁状态为无锁。

二、偏向锁

偏向锁,顾名思义,它会偏向于第一个访问锁的线程

  • 如果在运行过程中,同步锁只有一个线程访问,不存在多线程争用的情况,则线程是不需要触发同步的,这种情况下,就会给线程加一个偏向锁。线程第二次到达同步代码块时,会判断此时持有锁的线程是否就是自己,如果是则正常往下执行。由于之前没有释放锁,这里也就不需要重新加锁。如果自始至终使用锁的线程只有一个,很明显偏向锁几乎没有额外开销,性能极高。
  • 如果在运行过程中,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会消除它身上的偏向锁,将锁恢复到标准的轻量级锁。偏向锁通过消除资源无竞争情况下的同步原语,进一步提高了程序的运行性能。一旦有第二个线程加入锁竞争,偏向锁就升级为轻量级锁(自旋锁)。升级为轻量级锁的时候需要撤销偏向锁,撤销偏向锁的时候会导致STW(stop the word)操作;

锁竞争:如果多个线程轮流获取一个锁,但是每次获取锁的时候都很顺利,没有发生阻塞,那么就不存在锁竞争。只有当某线程尝试获取锁的时候,发现该锁已经被占用,只能等待其释放,这才发生了锁竞争。

三、轻量级锁(自选锁)

自旋锁:自旋锁原理非常简单,如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,它们只需要等一等(自旋),等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程和内核的切换的消耗。

  • 在轻量级锁状态下继续锁竞争,没有抢到锁的线程将自旋,即不停地循环判断锁是否能够被成功获取。长时间的自旋操作是非常消耗资源的,一个线程持有锁,其他线程就只能在原地空耗CPU,执行不了任何有效的任务,这种现象叫做忙等(busy-waiting)。如果锁竞争情况严重,某个达到最大自旋次数的线程,会将轻量级锁升级为重量级锁

四、重量级锁

  • 当后续线程尝试获取锁时,发现被占用的锁是重量级锁,则直接将自己挂起,等待将来被唤醒。在JDK1.6之前,synchronized直接加重量级锁,很明显现在得到了很好的优化。

重量级锁的特点:其他线程试图获取锁时,都会被阻塞,只有持有锁的线程释放锁之后才会唤醒这些线程。

优点缺点使用场景
偏向锁加锁和解锁不需要额外的消耗,和执行非同步方法比仅存在纳秒级的差距。如果线程间存在锁竞争,会带来额外的锁撤销的消耗。适用于只有一个线程访问同步块场景。
轻量级锁竞争的线程不会阻塞,提高了程序的响应速度。如果始终得不到锁竞争的线程使用自旋会消耗CPU。追求响应时间。同步块执行速度非常快。
重量级锁线程竞争不使用自旋,不会消耗CPU。线程阻塞,线程上下文切换耗费资源大,响应时间缓慢追求吞吐量。同步块执行速度较长。

锁升级场景

场景1: 经常只有某一个线程来加锁。

  • 加锁过程:也许获取锁的经常为同一个线程,这种情况下为了避免加锁造成的性能开销,加偏向锁
  • 偏向锁的执行流程如下:
    • 1、线程首先检查该对象头的线程ID是否为当前线程;
    • 2、A:如果对象头的线程ID和当前线程ID一直,则直接执行代码;B:如果不是当前线程ID则使用CAS方式替换对象头中的线程ID,如果使用CAS替换不成功则说明有线程正在执行,存在锁的竞争,这时需要撤销偏向锁,升级为轻量级锁。
    • 3、如果CAS替换成功,则把对象头的线程ID改为自己的线程ID,然后执行代码。
    • 4、执行代码完成之后释放锁,把对象头的线程ID修改为空。

场景2: 有线程来参与锁的竞争,但是获取锁的冲突时间很短。

  • 当开始有锁的竞争了,那么偏向锁就会升级到轻量级锁;
  • 线程获取锁出现冲突时,线程必须做出决定是继续在这里等,还是先去做其他事情,等会再来看看,而轻量级锁的采用了继续在这里等的方式。当发现有锁竞争,线程首先会使用自旋的方式循环在这里获取锁,因为使用自旋的方式非常消耗CPU。当一定时间内通过自旋的方式无法获取到锁的话,那么锁就开始升级为重量级锁了。

场景3: 有大量的线程参与锁的竞争,冲突性很高。

  • 当获取锁冲突多,时间越长的时候,线程肯定无法继续在这里死等了,所以只好先挂起,然后等前面获取锁的线程释放了锁之后,再开启下一轮的锁竞争,而这种形式就是我们的重量级锁。

————————————————
版权声明:本文为CSDN博主「carroll18」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_40722827/article/details/105598682

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一篇文章说清 :无锁、偏向锁、轻量级锁、重量级锁 的相关文章

  • 找到并标记Mesh顶点

    1 在Unity 3D中新建一个物体 本文以Cube为例 2 创建一个C 脚本 命名为MeshTest 3 在脚本中写入程序 在打开的脚本 MeshTest 上编写代码 xff0c 首先获取 MeshFilter 组件 xff0c 然后获取
  • TCP服务器端、客户端通讯(赋源码)

    实现通讯 xff0c 我们首先要知道是怎么样的一个流程 xff0c 下图是我画的一个通讯流程图 xff1a 一 Linux服务器端 我是在Ubuntu20 04下进行的 xff0c 使用的是C 43 43 xff0c 引入头文件socket
  • win11 命令 wmic:无效的指令 解决办法

    我想你肯定看到过让你修改环境变量的方法 但是 xff0c 如果你的电脑就根本没有装wmic xff0c 再怎么修改环境变量也是徒劳 我们打开设置 xff1a Win 43 I 点击应用 选择 可选功能 添加可选功能 搜索wmic xff0c
  • Python面向对象编程:关于类的方法中属性是否加前缀self的问题

    问题的缘起 今天完成了LeetCode首秀 xff08 而且是用刚学不久的python做的 xff09 xff0c 心情挺激动的 xff0c 毕竟之前只涉猎了竞赛OJ xff0c 没有在应用型平台上刷过题 xff0c 不妨定一个小目标 xf
  • 概念物理Ⅱ 第一讲:绪论

    目录 物理学研究的对象和动机为什么要研究物理学 xff1f 1 满足人类对大自然基本规律的好奇心2 改进技术 发展生产 两个动机之间的关系 物理学的发展历史起源于古希腊古典物理学时间 xff1a 牛顿时代 1900年经典力学 xff08 牛
  • Machine Learning:k近邻算法(KNN)

    目录 写在前面的话k 近邻算法概述优点缺点适用数据范围 原理Python代码实现Sklearn直接调用weights选项algorithm选项 算法测试与结果评价原理及方法函数主要参数说明Python代码实现 示例反思与总结 写在前面的话
  • 《Python爬虫技术:深入理解原理、技术与开发》读书笔记(一)

    目录 前言第1章 基础知识第2章 爬虫基础HTTP基础URL与URI超文本HTTP与HTTPSHTTP的请求过程Network面版 前言 这是本系列的第一篇文章 xff0c 文如其题 xff0c 这个系列旨在学习Python爬虫技术 本系列
  • 给软件工程师的自学建议

    给软件工程师的自学建议 与现在大学生的情况类似 xff0c 学校学的专业知识总是与实际工作中需要的知识相差甚远 或许进入我们这个行业就注定要一辈子不离书本 不离学习了 由于软硬件技术的推陈出新 xff0c 学校教的C Basic Pasca
  • Python基础入门—for循环

    Python基础入门 for循环 for 循环 xff1a range的使用 xff1a 循环控制语句 xff1a for else的使用 xff1a for循环嵌套 xff1a for 循环 xff1a for循环格式 xff1a for
  • 软件测试之项目总结全攻略

    在我们测试工作过程中 xff0c 由于公司业务发展 xff0c 快速迭代等原因 xff0c 我们遇到的项目以小项目居多 更新界面元素 xff0c 上个活动页 xff0c 优化一下原有的功能等等 xff0c 加上事情繁琐 xff0c 任务多
  • 教你用Python写一个京东自动下单抢购脚本(Python实现京东自动抢购)

    很多朋友都有网购抢购限量商品的经历 有时候蹲点抢怎么也抢不到 今天小编带你们学习怎么用Python写一个京东自动下单抢购脚本 以后再也不用拼手速拼网速啦 快来一起看看吧 1 问题背景 经过无数次抢购失败后 xff0c 发现商家会不定时的放出
  • JAVA基础题练习

    顺序插入 xff1a 插入有序 Scanner input 61 new Scanner System in char arr2 61 39 b 39 39 d 39 39 f 39 39 i 39 39 k 39 39 m 39 39 x
  • ubuntu20.04安装qq音乐并解决闪退问题

    在qq音乐官网下载linux版coco音乐 xff1a https y qq com download download html 下载deb包并且通过下面命令行安装 xff1a span class token function sudo
  • 架构师装逼核武器

    架构师这个职位是很多程序猿的梦想 xff0c 我有很多朋友私下和我聊天的时候 xff0c 曾多次问我要如何才能成为一个架构师 xff0c 对于这个问题 xff0c 我只能粗略的谈谈我个人的观点 xff0c 如有不同观点 xff0c 欢迎交流
  • 一文讲透java日志框架

    在项目开发过程中 xff0c 有一个必不可少的环节就是记录日志 xff0c 相信只要是个程序员都用过 xff0c 可是咱们自问下 xff0c 用了这么多年的日志框架 xff0c 你确定自己真弄懂了日志框架的来龙去脉嘛 xff1f 下面笔者就
  • HashMap底层原理

    在我们实际的项目中 xff0c HashMap这个集合类经常被用到 xff0c 可是就是这么一个常用的集合类 xff0c 却往往成了咱们面试中的绊脚石 即便你是个初级程序员 xff0c 也常会让你谈谈HashMap的底层原理 xff0c 今
  • 聊聊ThreadPoolExecutor线程池

    ThreadPoolExecutor是线程的池化技术 xff0c 也就是首先创建几个线程 xff0c 然后把线程放到池子里 xff0c 有任务来的时候直接从线程池中拉线程来执行任务 为什么要用池化技术 xff1f java中的线程是系统级别
  • Spring框架系列之bean的生命周期底层原理06

    bean的生命周期 xff0c 咱们必须从 AnnotationConfigApplicationContext的getBean方法开始 xff0c getBean顾名思义就是从Spring容器中得到一个Bean的实例对象 xff0c Sp
  • 电信运营商移动互联网发展分析

    电信运营商移动互联网发展分析 移动互联网是通信业发展的大趋势 xff0c 随着3G 和WiMAX 等高速无线接入技术的飞速发展 xff0c 移动互联网不仅继承固定互联网的很多技术 xff0c 并且在商务 娱乐以及移动性等方面拓展用户需求 自
  • Spring框架系列之bean的生命周期底层原理07

    上一篇我们预留了两个大的内容 xff0c 一个是Object sharedInstance 61 getSingleton beanName 从单例池中获取数据 xff0c 另外一个是getSingleton方法创建单例Bean xff0c

随机推荐

  • Spring框架系列之bean的生命周期底层原理08

    接着上一篇 xff0c 咱们继续doCreateBean方法的分析 xff0c doCreateBean内容比较多 xff0c 我们这次主要是把它的整体流程说下 xff0c 后续会逐个来分析每一个关键点 代码如下 xff1a protect
  • 2020-09-25 Python基础学习第三天笔记

    文章目录 一 可变字符串二 运算符三 列表1 列表的创建2 列表常用命令3 多维列表 四 元组 2020 9 24 Day3 一 可变字符串 需要原地修改字符串 xff0c 可以使用 io StringIO 对象或 array 模块 spa
  • Python Cookbook学习总结

    第一章 xff1a 数据结构和算法 任何序列 xff08 可迭代的对象 xff09 都可以通过一个简单的赋值操作来分解为单独的变量 xff0c 唯一的要求是变量的总数和结构要与序列相吻合 xff08 比如对于存储二维坐标等的二维数组 xff
  • SpringBoot解析yml/yaml/properties配置文件的四种方式汇总

    目录 一 配置文件注入方式一 64 Value 二 配置文件注入方式二 64 ConfigurationProperties 三 自定义解析类 xff0c 直接暴力读取yml配置文件 四 Spring配置文件的解析类Environment获
  • Linux下配置Apache为多端口 (centos7)

    apache设置多个不同的端口 xff0c 映射不同的文件 一 xff1a vim etc httpd conf httpd conf 查看http配置文件 滑倒最底部 xff0c 箭头标注的位置 我们需要进入该目录编辑 二 xff1a c
  • android11.0上通过广播屏蔽电源键功能

    framework base services core java com android server policy PhoneWindowManager java import java util HashSet import java
  • python和matlab实现随机攻击网络节点+蓄意攻击网络节点,实现最大连通子图比例、网络效率变化、平均距离变化等等。

    首先要有自己的邻接关系 xff0c 最好是邻接表 xff0c 如下图这样包括起点和终点 要在网络中读取自己的文件 xff0c 生成自己的复杂网络图 知道攻击方式包括哪些 xff1a 比如度 介数等 xff0c 选择自己想要的攻击方式 在研究
  • 2021-05-22

    第一个作业 xff1a 使用python编写一个数学表达式 注意 43 的运算顺序 xff0c 可以使用括号改变运算顺序 xff0c 和数学运算一样 第二个作业 xff1a 使用输入函数input xff08 提示符 xff09 xff0c
  • JavaScript变量的命名规则和命名规范

    变量的命名规则和命名规范 1 规则 你必须遵守 不然报错 1 1 一个变量只能由 数字 0 9 字母 a zA Z 美元符 划线下 组成 1 2 一个变量不能由 数字 开头 1 3 再 JS 中严格区分大小写 61 gt num Num N
  • 不惧掉签 | 苹果IPA安装包,免费自签教程

    最近连续更新了好几款 TikTok xff0c 基本上是刚更新没两天就掉签 大家也知道 xff0c 苹果的软件不像安卓 未上架App Store的软件只能签名后才能正常安装 不过 xff0c 好在国民手机管理软件 爱思助手 客户端也加入了
  • JavaScript把其他数据类型转换成字符串类型

    数据类型转换 转字符串 把其他数据类型转换成字符串类型 1 String 43 语法 String 你要转换的数据 43 返回值 转换好的数据 43 特点 61 gt 任何数据类型都能转换 2 toString 43 语法 你要转换的数据
  • JavaScript条件分支语句-switch语句

    条件分支语句 switch 43 语法 switch 要判断的变量 case 情况1 情况1执行的代码 break case 情况2 情况2执行的代码 break default 所有条件都不满足的时候执行的代码 43 注意 1 我们的每一
  • JavaScirpt - arguments

    arguments 43 在函数内部天生自带的变量 43 表示所有实参的集合 伪数组 arguments 的属性 1 length 61 gt 表示长度 arguments 里面由多少个数据 61 gt 其实就是你的函数调用由多少个实参 6
  • 简版弹幕实现。HTML+CSS+JAVASCRIPT

    思路 xff1a 1 设置video 2 设置输入框 3 获取输入框的内容 xff0c 添加 删除和更新 4 里面运用了单厂模式 xff0c 每次生成的例子都是一样的 span class token doctype lt DOCTYPE
  • webpack 模块加载原理

    webpack webpack 原理 1 webpack 模块加载原理 文件信息来源 xff1a webpack 深入理解模块加载原理 webpack 是一个模块打包器 xff0c 在它看来 xff0c 每一个文件都是一个模块 1 1 Co
  • 使用 FSL 和 TrackVis 分析 DTI 数据

    转载原文 使用 FSL 和 TrackVis 分析 DTI 数据 Alex 2018 05 21 free learner 64 163 com 弥散加权成像 xff08 Diffusion Weighted Imaging DWI xff
  • Java Swing界面设计UI(全)

    原文链接 http blog csdn net xietansheng article details 72814531 Java Swing GUI 图形界面窗口开发基础教程 xff0c 本教程将系统性地详细介绍 Java Swing 开
  • IntelliJ IDEA必会的几个常用设置

    IDEA 全称 IntelliJ IDEA xff0c 是java编程语言开发的集成环境 IntelliJ在业界被公认为最好的java开发工具 xff0c 以下归纳了初学者使用idea的一些常用设置 一 ctrl 43 滚轮调整页面大小 F
  • 什么是面向对象,它的三个基本特征:封装、继承、多态

    什么是面向对象思想 xff1f 已经学完了java确不知道如何跟别人解释面向对象是什么意思这很常见 让我们一起来回顾下这个奇思妙想 文章目录 一 面向对象与面向过程1 什么是面向过程 xff1f 2 什么是面向对象 xff1f 二 类与对象
  • 一篇文章说清 :无锁、偏向锁、轻量级锁、重量级锁

    文章目录 前言一 无锁二 偏向锁三 轻量级锁 xff08 自选锁 xff09 四 重量级锁锁升级场景 前言 JDK1 6为了减少获得锁和释放锁所带来的性能消耗 xff0c 引入了 偏向锁 和 轻量级锁 xff0c 所以在JDK1 6里锁一共