锁策略^o^

news2024/11/28 8:47:19

锁策略

一,悲观锁 VS 乐观锁

悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会碰上锁,这样别人想拿这个数据就会阻塞,直到它拿到锁。

乐观锁:假设数据一般不会发生修改,等到别人真的要修改了,就返回错误信息给用户,让用户决定如何去做,如果别人没有修改,那其实就相当于没有上锁,效率大大提高(其实这和懒汉模式有点相似的思路)。

二,重量级锁 VS轻量级锁

我们先了解一下其他概念:
锁的核⼼特性 “原⼦性”, 这样的机制追根溯源是 CPU 这样的硬件设备提供的,如下图:
在这里插入图片描述

  • CPU 提供了 “原子操作指令”.
  • 操作系统基于 CPU 的原⼦指令, 实现了 mutex 互斥锁.
  • JVM 基于操作系统提供的互斥锁, 实现了 synchronized 和 ReentrantLock 等关键字和类.
    重量级锁
    加锁机制重度依赖了 操作系统 提供的 mutex
  • 大量的内核态用户态切换
  • 很容易引发线程的调度
    这两个操作, 成本比较高. ⼀旦涉及到用户态和内核态的切换, 就意味着 “沧海桑田”.
    轻量级锁
    加锁机制尽可能不使用 mutex, ⽽是尽量在用户态代码完成. 实在搞不定了, 再使用mutex.
  • 少量的内核态用户态切换.
  • 不太容易引发线程调度.
    我们举个例子:
    假如:某天我们去银行办理业务,工作人员给了我们两个选择:
    1,直接将所有的材料交给他,让他帮我们办理
    2,我们在窗口外就将该打印该填写的表都弄完,然后再交给他
    想一想,我们应该选哪一个呢?可能大多数人都会选第一个,图省事。但是从效率的角度来讲第二个更加的高效,为什么呢?要知道去办理业务的可不止我们,银行的工作人员拿到的不一定只有我们的一份材料,所以他可能先将所有的材料都先整理在一块,然后统一给办理。这样对于我们来说是不是没有我们将所有的东西弄好直接办理快呢。
三,自旋锁 VS 挂起等待锁

自旋锁
按之前的⽅式,线程在抢锁失败后进⼊阻塞状态,放弃 CPU,需要过很久才能再次被调度.但实际上, ⼤部分情况下,虽然当前抢锁失败,但过不了很久,锁就会被释放。没必要就放弃 CPU. 这个时候就可以使⽤⾃旋锁来处理这样的问题
伪代码

1 while (抢锁(lock) == 失败) {}

如果获取锁失败, ⽴即再尝试获取锁, ⽆限循环, 直到获取到锁为⽌. 第⼀次获取锁失败, 第⼆次的尝试会在极短的时间内到来.⼀旦锁被其他线程释放, 就能第⼀时间获取到锁.
挂起等待锁
这个锁其实和自旋锁是有点相反的,该锁在获取锁失败后会直接进入阻塞状态,放弃CPU,需要很久才能被调度,这也就是之前我们最常用到的锁。
为了更好理解,举个例子:
想象⼀下, 去追求⼀个⼥神. 当男⽣向⼥神表⽩后, ⼥神说: 你是个好⼈, 但是我有男朋友了~~
挂起等待锁: 陷⼊沉沦不能⾃拔… 过了很久很久之后, 突然⼥神发来消息, “咱俩要不试试?” (注意, 这个很⻓的时间间隔⾥, ⼥神可能已经换了好⼏个男票了).
⾃旋锁: 死⽪赖脸坚韧不拔. 仍然每天持续的和⼥神说早安晚安. ⼀旦⼥神和上⼀任分⼿, 那么就能⽴刻抓住机会上位.

四,公平锁VS非公平锁

假设三个线程 A, B, C. A 先尝试获取锁, 获取成功. 然后 B 再尝试获取锁, 获取失败, 阻塞等待; 然后 C也尝试获取锁, C 也获取失败, 也阻塞等待.
当线程 A 释放锁的时候, 会发⽣啥呢?
公平锁: 遵守 “先来后到”. B ⽐ C 先来的. 当 A 释放锁的之后, B 就能先于 C 获取到锁.
非公平锁: 不遵守 “先来后到”. B 和 C 都有可能获取到锁.
举个例子
这就好⽐⼀群男⽣追同⼀个⼥神. 当⼥神和前任分⼿之后, 先来追⼥神的男⽣上位, 这就是公平锁; 如果是⼥神不按先后顺序挑⼀个⾃⼰看的顺眼的, 就是⾮公平锁.
在这里插入图片描述
非公平锁:在这里插入图片描述
其实上述的所谓公平和非公平并不是有什么特殊的含义,其实有些含义可能与我们日常的想法还相反。这都是乌龟的屁股————“ 规定 ”。前人定的,我们照着用就行了。
注意

  • 操作系统内部的线程调度就可以视为是随机的. 如果不做任何额外的限制, 锁就是⾮公平锁. 如果要想实现公平锁, 就需要依赖额外的数据结构, 来记录线程们的先后顺序.
  • 公平锁和⾮公平锁没有好坏之分, 关键还是看适⽤场景
  • synchronized是非公平锁。
五,可重入锁 VS 不可重入锁
  • 可重入锁的字面意思就是“ 可以重新进入的锁 ” 即:允许同一线程多次获取同一把锁。
    比如一个递归函数里有加锁操作,递归过程中这个锁会阻塞自己吗?如果不会,那么这个锁就是可重入锁*(出于这个原因,也叫做递归锁)。
  • Java里面只要是以Reetrant 开头命名的锁都是可重入锁,而且JDK 提供的所有现成的Lock 实现类,包括synchronized 关键字都是可重入的
  • 但是Linux 系统提供的mutex 是不可重入锁。
  • 理解:“把自己锁死”:一个线程没有释放锁,然后又尝试再次加锁。
  • 举个例子:
    在这里插入图片描述
  • synchronized就是不可重入锁。
六,读写锁
  • 多线程之间,数据的读取方之间不会产⽣线程安全问题,但数据的写⼊方互相之间以及和读者之间都需要进⾏互斥。如果两种场景下都⽤同⼀个锁,就会产⽣极⼤的性能损耗(这是由于,我们的读操作本来就不需要加锁,而如果平白一个锁,就是多此一举,很降低效率)。所以读写锁因此⽽产⽣。
  • 复读者之间并不互斥,⽽写者则要求与任何⼈互斥。
    线程安全问题
  • 两个线程都只是读⼀个数据, 此时并没有线程安全问题. 直接并发的读取即可.
  • 两个线程都要写⼀个数据, 有线程安全问题.
  • ⼀个线程读另外⼀个线程写, 也有线程安全问题
    为了解决上诉的线程安全问题,. Java 标准库提供了 ReentrantReadWriteLock 类, 实现了读写锁
  • ReentrantReadWriteLock.ReadLock 类表⽰⼀个读锁. 这个对象提供了 lock / unlock ⽅法
    进⾏加锁解锁.
  • ReentrantReadWriteLock.WriteLock 类表⽰⼀个写锁. 这个对象也提供了 lock / unlock⽅法进⾏加锁解锁.
    注意
  • 读加锁和读加锁之间, 不互斥.
  • 写加锁和写加锁之间, 互斥.
  • 读加锁和写加锁之间, 互斥.
  • 只要是涉及到 “互斥”, 就会产⽣线程的挂起等待. ⼀旦线程挂起, 再次被唤醒就不知道隔了多久了.因此尽可能减少 “互斥” 的机会, 就是提⾼效率的重要途径.
  • 读写锁特别适合于 “频繁读, 不频繁写” 的场景中. (这样的场景其实也是⾮常⼴泛存在的,如: 利用教务系统点名)
  • synchronized 不是读写锁
七,相关题目:
    1. 你是怎么理解乐观锁和悲观锁的,具体怎么实现呢?
      悲观锁:当多个线程同时访问同一个共享变量的时候,总是认为会出现线程安全问题,无论什么时候都按最坏的情况来处理,每次都要加锁
      乐观锁:当多个线程同时访问同一个共享变量的时候,认为大概率不会出现线程安全问题,直接访问数据,在访问的同时识别一下是否会出现线程安全问题。
  • 2,介绍下读写锁?
    读写锁:就是将读操作和写操作分别加锁
    读和读之间不互斥
    写和写之间互斥
    读和写之间互斥
    读写锁多用在 “ 频繁读,不频繁写”的场景中
  • 3,什么是自旋锁,为什么要使用自旋锁策略呢,缺点是什么?
    自旋锁:就是当一个线程加锁失败时再次重新尝试获取锁,不会阻塞等待退出线程调度,而是一直占据CPU,一直在无限循环,直到锁被释放,能第一时间获取锁
    优点:没有放弃CPU资源,自旋锁能在锁释放之后,第一时间获取到锁,在锁持有比较短的场景下,非常有用。
    缺点:它会一直占据CPU资源
  • 4,synchronized 是可重入锁么?
    是可重入锁。
    可重入锁指的是连续两次加锁不会导致死锁。
    (实现的方式是在锁中记录该锁持有的线程身份,以及一计数器,如果发现当前加锁的线程就是持有锁的线程,则直接计数自增)

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

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

相关文章

如何理解服务器的硬防和软防

关于服务器防御相关的知识很多新手都不是很了解,服务器防御分为服务器硬防和软防。 一、服务器硬防 服务器硬防主要指的是硬件防火墙,能够在硬件设备中嵌入防火墙的防御程序,是一种专门用来保护网络不受未授权访问所设计的设备,硬…

保护你的数据隐私!新技术将实现绝对安全的「量子云计算」

听说过物质-光子混合实现可验证的盲量子计算(blind quantum computing)吗? "盲量子计算"是一种使用户能够远程利用量子计算服务商的量子设备执行计算的模式。这一技术可能使数百万个人和企业安全地接入下一代量子计算机&#xff0c…

Big Data and Cognitive Computing (IF=3.7) 计算机/大数据/人工智能期刊投稿

Special Issue: Artificial Cognitive Systems for Computer Vision 欢迎计算机/大数据/人工智能/计算机视觉相关工作的投稿! 影响因子3.7,截止时间2024年12月31日 投稿咨询:lqyan18fudan.edu.cn 投稿网址:https://www.mdpi.com/j…

负荷预测 | Matlab基于TCN-GRU-Attention单变量时间序列多步预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于TCN-GRU-Attention单变量时间序列多步预测; 2.单变量时间序列数据集,采用前12个时刻预测未来96个时刻的数据; 3.excel数据方便替换,运行环境matlab2023及以…

创纪录的里程碑!光镊阵列捕获逾6,000中性原子,量子计算再达新高

论文链接: https://arxiv.org/abs/2403.12021 2024年3月18日,研究人员成功开发出一种大规模光镊阵列,能够在12,000个位点上捕获超过6,100个中性原子,同时在几个关键性能指标上达到新的高度: 1)相干时间达到…

智慧公厕解决方案易集成好使用的智能硬件

在现代城市建设中,智慧公厕的需求日益增长。为了提供更好的用户体验和更高效的管理,易集成、好使用的智能硬件成为智慧公厕解决方案的关键组成部分。 1. 蹲位有人无人感应器:是用于检测厕位有人无人的设备,根据现场不同的安装条件…

BTI功能验证与异常解析

BTI分支目标识别精讲与实践系列 思考 1、什么是代码重用攻击?什么是ROP攻击?区别与联系? 2、什么是JOP攻击?间接分支跳转指令? 3、JOP攻击的缓解技术?控制流完整性保护? 4、BTI下的JOP如何…

AGV小车 | 提升仓储物流运营效率的好帮手

agv 随着物联网、机器视觉、仓储机器人、无人机等新技术的应用,物流仓储自动化技术正在以较快的速度发生变革。仓储机器人在智能仓储系统中的应用不仅为物流安全保驾护航也助力智能物流发展。 市场的爆发一方面来源于需求的增长,从传统的制造业到电商业…

mp4怎么改m4v发微信?教你发微信视频不被压缩。

在微信发送一般的MP4视频时,为了便于传输速度,微信会对其进行视频压缩,但是微信对于m4v格式却不会压缩。 m4v是一种应用于网络视频点播网站和移动手持设备的视频格式,由苹果公司创造,基于mpeg-4编码第二版&#xff0c…

飞桨Ai(二)paddle使用CPU版本可以正常识别,切换为GPU版本时无法识别结果

一、问题描述: 刚开始用paddle的CPU版本,对训练好的模型进行推理,正常识别出想要的结果后来尝试使用paddle的GPU版本,然后发现识别出来是空的 二、系统思路: 最终系统环境如下: 系统:win10 …

【考研数学】全年各阶段用书汇总+资料分享

我一战备考很迷茫,身边室友也都是,和室友一起去买资料,网上推荐的看到了就都买了 大家都不知道怎么样才能选对数学参考书然后快速进入备考状态,最后犹犹豫豫买了一堆资料都没有正式开始备考... 从小都算是身边人口中“偏科&…

Rabbit MQ------>延迟队列!!!

一、场景: 1.定时发布文章 2.秒杀之后,给30分钟时间进行支付,如果30分钟后,没有支付,订单取消。 3.预约餐厅,提前半个小时发短信通知用户。 A -> 13:00 17:00 16:30 延迟时间: 7*30 * 60…

Docker仅需3步搭建免费私有化的AI搜索引擎-FreeAskInternet

简介 FreeAskInternet 是一个完全免费、私有且本地运行的搜索引擎,并使用 LLM 生成答案,无需 GPU。用户可以提出问题,系统会进行多引擎搜索,并将搜索结果合并到ChatGPT3.5 LLM中,并根据搜索结果生成答案。 什么是 Fr…

最新彩虹知识付费商城源码 V3.4

最新彩虹知识付费商城源码 V3.4,支持二级分类,多级分销,秒杀,砍价,团购,首页继续浏览,分站个人虚拟余额自定义,最新批量对接,批量下载图片,批量替换标题&…

6本期刊直接被踢!!最新4月SCI/SSCI期刊目录更新,请查收~

又到了一月一度的科睿唯安官网更新Web of Science核心期刊目录的时候,小编今天带大家一起来看看最新的SCI/SSCI期刊目录有哪些变化吧。 继上次SCI期刊目录和SSCI期刊目录更新之后,本次4月更新共有9本期刊发生变动: • SCIE:有5本期…

【重装系统】分配D盘

1.右键“此电脑”,点击管理 2.选择“存储”–磁盘管理 3.右键未分配磁盘–新建简单卷 4.一路默认设置即可

【零基础入门TypeScript】模块

目录 内部模块 内部模块语法(旧) 命名空间语法(新) 两种情况下生成的 JavaScript 是相同的 外部模块 选择模块加载器 定义外部模块 句法 例子 文件:IShape.js 文件:Circle.js 文件:…

Jmeter 简单的压力测试

今天我们一起利用Apache Jmeter(一种接口测试工具)来进行压力测试学习。压力测试主要目的是测试负载均衡的实现效果。 安装Jmeter这里就不做阐述了,上网下载个最新版就可以了,因为Jmeter是由JAVA语言开发的,所以安装之…

入侵检测数据预处理 特征工程 面临的问题

数据预处理 对于分类任务来说,由于原始数据可能存在异常、缺失值以及不同特征的取值范围差 异大等问题,对机器学习会产生影响,因此,在进行机器学习模型训练之前,需要先对数据 进行预处理。数据预处理的主要过程包括数据清洗、去量纲、离散化等。 1.数据清洗 对采集到的数据进行…

数据结构之单链表的相关知识点及应用

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏:数据结构 目录 链表的概念及结构 链表与顺序表的区别与优劣势 链表的分类 单链表的实现 单链表中增加节点 单链表中尾插数据 打印单链…