【多线程】乐观/悲观锁、重量级/轻量级锁、挂起等待/自旋锁、公平/非公锁、可重入/不可重入锁、读写锁

news2025/1/12 20:42:00

文章目录

  • 乐观锁和悲观锁
  • 重量级锁和轻量级锁
  • 挂起等待锁和自旋锁
  • 公平锁和非公平锁
  • 可重入锁和不可重入锁
  • 读写锁
  • 相关面试题

:非常广义的概念,不是指某个具体的锁,所有的锁都可以往这些策略中套
synchronized:只是市面上五花八门的锁种,其中一种典型的实现,Java 内置的,推荐使用的锁

乐观锁和悲观锁

这两个词不是指某个具体的锁,而是锁的一种“特性”,描述了“一类”

乐观锁:加锁的时候,假设出现冲突的概率不大

  • 接下来围绕加锁要做的工作就会更少
    悲观锁:加锁的时候,假设出现锁冲突的概率很大
  • 接下来围绕加锁要做的工作就会更多

使用 synchronized,初始情况下,是乐观的(预估接下来锁冲突概率不大)

  • 同时会在背后偷偷地统计锁冲突了多少次
  • 如果发现锁冲突达到一定程度了,就会转变为“悲观的”
    乐观锁和悲观锁需要做的事情是不同的
  • 乐观做的事情少一点
  • 悲观做的事情往往更重量级

站在预测锁冲突的概率是否高
synchronized 是自适应的

重量级锁和轻量级锁

效果和悲观乐观是重叠的,只是站在的角度不一样

重量级锁:加锁的开销比较大,要做的工作更多

  • 往往悲观的时候,会做的
    轻量级锁:加锁的开销比较小,要做的工作相对更少
  • 往往乐观的时候,会做的
    但也不能认为是 100%等价,因为:
  • 乐观和悲观是站在“预估所冲突”角度
  • 重量轻量是站在“加锁开销“角度

站在加锁的开销角度
synchronized 也是自适应的

挂起等待锁和自旋锁

挂起等待锁:属于是悲观锁/重量级锁的一种典型实现
自旋锁:乐观锁/轻量级锁的一种典型实现

比如:
你去追你的女神:
女神女神,我好喜欢你,

  • 你尝试对女神加锁
    女神表示:我有男朋友了

  • 女神表示她这把锁已经被别的线程给加了
    你就可以选择“等待”,等到女神锁被释放,比如:

  • 你选择每天仍然会给女神不停地问候“早安,午安…”,这里的行为称为“自旋锁

    • 这里的等待是“忙等”,等待的过程中 CPU 的资源不会释放
    • 某天女神和男朋友吵架了,不开心,你就立刻能感知到,机会来了。这样你就可以在女神锁释放的第一时间,立刻抓住机会,能够上位
    • 不停地,循环地检测锁是否被释放,一旦锁释放,就能立即有机会能获得锁
  • 你选择把女神拉黑,先不联系了,若干年后你从别人那里听说,女神分手了,你再去联络女神,这种行为就是“挂起等待锁

    • 不联系,就相当于“让出 CPU 资源”CPU 就可以去做别的事了
    • 不理女神之后,我们就可以有心思好好学习,好好敲代码,好好找工作了,在过程中做成更多的事情。过了一段时间后,我们通过一些途径听说女神分手了,再伺机而动,但“听说”的时效性很低,这个中间可能有很长的时间跨度。在这个时间跨度里,女神是否由谈了男朋友?分手了多少次?你是不知道的
    • 挂机时间更长,但能节省下 CPU 资源去做别的事情

注意:

  • 只有在假定锁冲突概率不高的情况下,才能“忙等”。如果好几个线程都在竞争同一个锁,一个线程拿到锁,其他的都在“忙等”,这样总的 CPU 消耗就会非常高
  • 而且,由于竞争太激烈,导致有些线程要等待很久才能拿到锁
  • 锁冲突很高的概率很高的话就不适合“自旋锁”方案

  • 挂起等待锁也就适合“悲观锁”这样的场景了
  • 锁竞争非常激烈,预测拿到锁的概率本身就不打,不放吧 CPU 让出来,充分的做其他事情

synchronized“自适应”

  • 轻量级锁就是基于自旋的方式实现的(JVM 内部,用户态代码实现)
  • 重量级锁就是基于挂起等待的方式实现的(调用操作系统 API,在内核中实现)
    纯用户态代码往往执行效率比内核态代码的高一些,总体来说,我们还是认为“自旋”的效率更高的,但是 CPU 开销更大
    挂起等待锁的操作虽然 CPU 开销变少了,但整体的等待时间更多

公平锁和非公平锁

日常生活中,说的公平可能有不同的含义


image.png|521
当女神分手了,该轮到谁上位呢?

公平锁: 在计算机中,约定“先来后到”为公平
image.png|556


非公平锁: 系统原生
image.png|365


synchronized 属于非公平锁

  • N 个线程竞争同一个锁,其中一个线程拿到锁了,后续该线程释放锁之后,剩下的 N-1 个线程,就要重新竞争锁,谁能拿到锁,就不一定了
  • 当然,也不能保证这些线程竞争中获取的概率一定是数学上的严格均等
    本身操作系统内核里针对锁的处理就是如此,synchronized 在系统内核的基础上,没有做啥额外的操作

如需要使用公平锁,就需要做额外的工作

  • 比如引入队列,记录每个线程加锁的顺序

可重入锁和不可重入锁

死锁问题:如果一个线程,针对同一把锁,连续加锁两次,就可能出现死锁,如果把锁设为“可重入”就可以避免死锁了

可重入:是专门的计算机术语,不要写作“可重复”这样的词

可重入锁

  • 会记录当前是哪个线程持有了这把锁
  • 在加锁的时候判定,当前申请锁的线程,是否就是锁的持有者
  • 计数器,记录加锁的次数,从而确定何时真正释放锁
    • 遇到一个 { 加一次锁,计数器加一
    • 遇到一个 } 解锁一次,计数器减一
    • 等到计数器为零,真正释放锁

读写锁

synchronized 并非是读写锁
所谓的读写锁,把“加锁操作”分为两种情况

  • 读加锁
  • 写加锁
    如果多个线程同时读这个变量,没有线程安全问题,但是
  • 一个线程读/一个线程写
  • 两个线程都写
    就会产生问题

在实际开发中,在大部分场景下,读操作的频次,本身就比写操作的频次高。所以就让读操作不产生锁冲突,这样就只有少数写操作会产生冲突,这样效率就高了


读写锁提供了两种加锁的 API,系统内置的锁,Java 标准库中的读写锁类为:ReentrantReadWriteLock

  • 加读锁
    • ReentrantReadWriteLock 的内部类 ReentrantReadWriteLock.ReadLock 表示加读锁,这个对象提供了 lock/unlock ⽅法进⾏加锁解锁
  • 加写锁
    • ReentrantReadWriteLock 的内部类 ReentrantReadWriteLock.WriteLock 表示加写锁,这个对象也提供了lock/unlock ⽅法进⾏加锁解锁
      解锁的 API 是一样的,就需要把 unlock 放到 finally 中,确保能够执行到
  • 如果两个线程都是按照读方式加锁,此时不会产生锁冲突;
  • 如果两个线程都是家写锁,此时会产生锁冲突
  • 如果一个线程读锁,一个线程写锁,也会产生冲突

相关面试题

image.png


image.png


image.png


image.png

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

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

相关文章

新形势下职业教育云计算人才培养策略

一、引言 在数字化转型的浪潮中,云计算作为核心技术之一,正在深刻影响着各行各业的发展。职业教育作为培养技术技能型人才的重要途径,需要紧跟时代步伐,不断优化和创新云计算人才培养模式,以满足社会对云计算人才的迫…

基于MyBatis-plus的SpringBoot开发

目录 一、SpringBoot整合mybatis 二、SpringBoot整合mybatis-plus 1、什么是mybatis-plus? 2、mybatis-plus的特性 3、mybatis-plus的使用 (1)编写注解配置实体类与关系表映射关系 (2)mapper层 (3…

Sandbox: rsync.samba(80134) deny(1) file-write-create

Xcode15运行报错:Sandbox: rsync.samba(80134) deny(1) file-write-create/xxx/xxx 如下图: 解决办法: Build Settings 搜索 sandbox,把 Build Options 中的 User Script Sandboxing改为 NO

iPhone很多空相簿怎么删除:简化你的照片库

随着我们使用iPhone拍摄越来越多的照片和视频,管理这些内容的需求也随之增加。创建相簿是组织照片的一种便捷方式,但随着时间的推移,可能会产生许多未使用或空的相簿。这些空相簿不仅占用了照片应用的界面空间,也让照片库显得更加…

代码随想录算法训练营第四十二天|广度优先搜索理论基础、岛屿数量:深搜版、岛屿数量:广搜版

广度优先搜索理论基础 广搜(bfs)是一圈一圈的搜索过程。因为广搜是从起点出发,以起始点为中心一圈一圈进行搜索,一旦遇到终点,记录之前走过的节点就是一条最短路。 广搜的过程:我们从图中可以看出&#x…

HTML+CSS进阶用法(上)——平面转换、渐变、空间转换

欢迎来到CSS变换的世界,这里充满了创意和可能性。在本篇博客中,我们将一起学习如何使用transform属性来实现各种平面和空间转换效果,包括位移、旋转、缩放,以及如何通过渐变和动画来增强我们的网页设计。无论你是初学者还是有经验…

【区块链+金融服务】基于区块链的区域股权金融综合服务平台 | FISCO BCOS应用案例

区域性股权市场是我国资本市场的重要组成部分,是多层次资本市场体系的基石。区块链技术与区域性股权市场 分散特征天然匹配,从新型金融基础设施层面为场外参与各方提供公共的可信服务,以技术手段完善市场基础条 件,弥补区域性短板…

仿RabbiteMq实现简易消息队列正式篇(需求分析)

TOC 目录 MQ的实现方法 RabbitMq中的相关概念 消息队列系统模块划分 总体划分 服务端模块 数据管理模块 虚拟机数据管理模块 交换机路由模块 消费者管理模块 信道(通信)管理模块 连接管理模块 服务端BrokerServer模块 客户端模块 消费者管…

iPhone 16 机模视频曝光,五种颜色各有千秋

科技博主的最新视频分享了苹果 iPhone 16 标准版的机模上手体验。 视频中展示了五种颜色的 iPhone 16:深邃的蓝色、柔和的粉色、纯净的白色、经典的黑色和生机勃勃的绿色。 与 iPhone 15 相比,iPhone 16 弃用了黄色,新增了白色,…

等保测评中的供应链安全管理:构建安全的数字生态

在数字化转型的浪潮中,供应链已成为企业运营的核心环节,同时也是信息安全的潜在脆弱点。等保测评,作为我国信息安全等级保护制度的重要组成部分,对供应链安全管理提出了明确的要求,旨在构建一个安全、可靠的数字生态。…

Vue 3+Vite+Eectron从入门到实战系列之(六)一工作台界面开发及实现响应式

工作台&#xff0c;是每个后台系统必备的&#xff0c;也是管理系统的首页。这次我们来实现一个工作台&#xff0c;并适配他的响应性 实现效果 代码实现 <template><div class"dashboard"><el-row :gutter"20"><el-col class"mb…

小程序学习day06-wx:for续、WXSS模版样式、rpx尺寸单位、@import、全局样式与局部样式、全局配置

25、wx&#xff1a;for续 &#xff08;5&#xff09;手动指定索引和当前项的变量名 1&#xff09;使用wx:for-index可以指定当前循环项的索引变量名 2&#xff09;使用wx:for-item可以指定当前项的变量名 &#xff08;6&#xff09;wx:key的使用 类似于Vue列表渲染中的:key&a…

2025考研西安电子科技大学马克思主义理论经验贴

学长从西安电子科技大学马克思主义理论专业毕业&#xff0c;现从事高校思政课工作&#xff0c;拥有三年西安电子科技大学马理论考研辅导经验&#xff0c;现写出2025西安电子科技大学马克思主义理论经验贴供大家参考。 一、选学校 选学校首先考虑的是就业&#xff0c;因为咱们…

【书生大模型实战营(暑假场)】基础任务四 InternLM+LlamaIndex RAG 实践

基础任务四 InternLMLlamaIndex RAG 实践 任务文档视频Retrieval-Augmented Generation for Large Language Models: A Survey 文章目录 基础任务四 InternLMLlamaIndex RAG 实践1 理解RAG&#xff0c;使用 RAG1.1 RAG技术概览1.2 RAG工作原理1.3 向量数据库 Vector-DB1.4 RAG…

多态(二)

1. final &#xff1a;修饰虚函数&#xff0c;表示该虚函数不能再被重写 class Car { public:virtual void Drive() final {} }; class Benz :public Car { public:virtual void Drive() {cout << "Benz-舒适" << endl;} }; 2. override: 检查派生类…

如何选取网络中间的输出?并极简方法可视化

文章目录 一、提供几种方法1. 直接修改模型的 forward 方法&#xff1a;2. 使用 hook 函数&#xff1a;3. 直接访问模型的子模块&#xff1a;4. 使用 nn.Sequential 来提取中间层&#xff1a; 2. 如何选择方法3. 实际操作——提取特征并可视化1. 可视化2. 提取特征 一、提供几种…

无人机之电池注意事项

1、外场作业时&#xff0c;电池一定要放置在阴凉处&#xff0c;避免太阳直射&#xff1b; 2、刚作业完的电池发热严重时&#xff0c;请降至室温再充电&#xff1b; 3、注意电池状态&#xff0c;一旦发现电池出现鼓包、漏液等现象&#xff0c;必须马上停止使用&#xff1b; 4…

基于springboot的医院资源管理系统

TOC springboot158基于springboot的医院资源管理系统 第1章 绪论** 1.1 课题背景 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供…

Redmi 13C 5G 红米13R 5G 解锁BL 降级 MIUI 秒解锁BL 澎湃OS 降级

机型名称 &#xff1a;Redmi 13C 5G/ Redmi 13R 5G/ POCO M6 5G 机型代号 &#xff1a;air HyperOS 降级MIUI 14 澎湃OS 或者miui都可以秒解锁BL&#xff0c; Redmi 13C 5G 红米13R 5G 解锁BL 降级 MIUI 秒解锁BL 澎湃OS 降级,手机ROM - Powered by Discuz!点击上方 下载对…

大迈u盘文件不见了怎么办?全面解析与恢复策略

在数字化时代&#xff0c;U盘作为我们日常工作、学习和生活中不可或缺的存储设备&#xff0c;承载着大量的重要文件。然而&#xff0c;面对突如其来的U盘文件丢失问题&#xff0c;许多用户往往会感到手足无措&#xff0c;甚至因此遭受不可估量的损失。本文将围绕“大迈U盘文件丢…