乐观锁、悲观锁知识详解

  • 互斥锁与自旋锁

    • 最底层的两种就是会「互斥锁和自旋锁」

    • 加锁的目的就是保证共享资源在任意时间里,只有一个线程访问,这样就可以避免多线程导致共享数据错乱的问题。

    • 互斥锁和自旋锁对于加锁失败后的处理方式是不一样的:

      • 互斥锁加锁失败后,线程会释放 CPU ,给其他线程;

      • 自旋锁加锁失败后,线程会忙等待,直到它拿到锁;

    • 互斥锁是一种「独占锁」

    • 对于互斥锁加锁失败而阻塞的现象,是由操作系统内核实现的

    • 那这个开销成本是什么呢?会有两次线程上下文切换的成本

      • 当线程加锁失败时,内核会把线程的状态从「运行」状态设置为「睡眠」状态,然后把 CPU 切换给其他线程运行;

      • 接着,当锁被释放时,之前「睡眠」状态的线程会变为「就绪」状态,然后内核会在合适的时间,把 CPU 切换给该线程运行。

    • 线程的上下文切换的是什么?当两个线程是属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据。

    • 如果你能确定被锁住的代码执行时间很短,就不应该用互斥锁,而应该选用自旋锁,否则使用互斥锁。

    • 自旋锁是通过 CPU 提供的 CAS 函数(Compare And Swap),在「用户态」完成加锁和解锁操作,不会主动产生线程上下文切换,所以相比互斥锁来说,会快一些,开销也小一些。

    • 一般加锁的过程,包含两个步骤:

      • 第一步,查看锁的状态,如果锁是空闲的,则执行第二步;

      • 第二步,将锁设置为当前线程持有;

      • CAS 函数就把这两个步骤合并成一条硬件级指令,形成原子指令,这样就保证了这两个步骤是不可分割的,要么一次性执行完两个步骤,要么两个步骤都不执行。

    • 使用自旋锁的时候,当发生多线程竞争锁的情况,加锁失败的线程会「忙等待」,直到它拿到锁。这里的「忙等待」可以用 while 循环等待实现,不过最好是使用 CPU 提供的 PAUSE 指令来实现「忙等待」,因为可以减少循环等待时的耗电量。

    • 需要注意,在单核 CPU 上,需要抢占式的调度器(即不断通过时钟中断一个线程,运行其他线程)。否则,自旋锁在单 CPU 上无法使用,因为一个自旋的线程永远不会放弃 CPU。

    • 自旋锁开销少,在多核系统下一般不会主动产生线程切换,适合异步、协程等在用户态切换请求的编程方式,但如果被锁住的代码执行时间过长,自旋的线程会长时间占用 CPU 资源,所以自旋的时间和被锁住的代码执行的时间是成「正比」的关系

    • 当加锁失败时,互斥锁用「线程切换」来应对,自旋锁则用「忙等待」来应对。

  • 读写锁

    • 读写锁适用于能明确区分读操作和写操作的场景

    • 读写锁的工作原理是:

      • 当「写锁」没有被线程持有时,多个线程能够并发地持有读锁,这大大提高了共享资源的访问效率,因为「读锁」是用于读取共享资源的场景,所以多个线程同时持有读锁也不会破坏共享资源的数据。

      • 但是,一旦「写锁」被线程持有后,读线程的获取读锁的操作会被阻塞,而且其他写线程的获取写锁的操作也会被阻塞。

    • 写锁是独占锁,因为任何时刻只能有一个线程持有写锁,类似互斥锁和自旋锁,而读锁是共享锁,因为读锁可以被多个线程同时持有。

    • 读写锁在读多写少的场景,能发挥出优势。

    • 读写锁可以分为「读优先锁」和「写优先锁」。

      • 读优先锁期望的是,读锁能被更多的线程持有,以便提高读线程的并发性

      • 写优先锁是优先服务写线程

    • 既然不管优先读锁还是写锁,对方可能会出现饿死问题

    • 公平读写锁比较简单的一种方式是:用队列把获取锁的线程排队,不管是写线程还是读线程都按照先进先出的原则加锁即可,这样读线程仍然可以并发,也不会出现「饥饿」的现象。

  • 乐观锁和悲观锁

    • 互斥锁自旋锁、读写锁,都是属于悲观锁

    • 悲观锁做事比较悲观,它认为多线程同时修改共享资源的概率比较高,于是很容易出现冲突,所以访问共享资源前,先要上锁。

    • 如果多线程同时修改共享资源的概率比较低,就可以采用乐观锁

    • 乐观锁做事比较乐观,它假定冲突的概率很低,先修改完共享资源,再验证这段时间内有没有发生冲突,如果没有其他线程在修改资源,那么操作完成,如果发现有其他线程已经修改过这个资源,就放弃本次操作。

    • 乐观锁全程并没有加锁,所以它也叫无锁编程。

    • 小例子

      • 我们常见的 SVN 和 Git 也是用了乐观锁的思想,先让用户编辑代码,然后提交的时候,通过版本号来判断是否产生了冲突,发生了冲突的地方,需要我们自己修改后,再重新提交。

    • 乐观锁虽然去除了加锁解锁的操作,但是一旦发生冲突,重试的成本非常高,所以只有在冲突概率非常低,且加锁成本非常高的场景时,才考虑使用乐观锁

    • 乐观锁是先修改同步资源,再验证有没有发生冲突。悲观锁是修改共享数据前,都要先加锁,防止竞争。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习】数据探索(Data Exploration)---数据质量和数据特征分析

一、引言 在机器学习项目中,数据探索是至关重要的一步。它不仅是模型构建的基础,还是确保模型性能稳定、预测准确的关键。数据探索的过程中,数据质量和数据特征分析占据了核心地位。数据质量直接关系到模型能否从数据中提取有效信息&#xff…

Day24:私信列表、私信详情、发送私信

测试用户:用户名aaa 密码aaa 查询当前用户的会话列表;每个会话只显示一条最新的私信;支持分页显示。 首先看下表结构: conversation_id: 用from_id和to_id拼接,小的放前面去(因为两个人的对话应该在一个会…

Linux:详解TCP报头类型

文章目录 温习序号的意义序号和确认序号报文的类型 TCP报头类型详解ACK: 确认号是否有效SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段FIN: 通知对方, 本端要关闭了PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走RST: 对方要求重新建立连接; 我们把携带RST标识的称…

【学习】软件企业何时会选择第三方软件测试机构

近年来,随着软件行业的迅猛发展,软件企业对软件测试的需求也越来越大。为了保证软件的质量和稳定性,许多企业选择寻找第三方软件测试机构来进行软件测试。第三方软件测试机构是独立于软开发企业的专业机构,主要从事软件测试和质量…

【SpringBoot从入门到精通】02_SpringBoot快速上手

二、SpringBoot快速上手 环境准备: Java8及以上 Maven3.5 https://docs.spring.io/spring-boot/docs/2.7.14/reference/html/getting-started.html#getting-started SpringBoot 2.x 最新版 开发工具: IDEA 2022 2.1 开发第一个SpringBoot应用程序 …

什么是土壤墒情检测站?它在农业生产中有什么作用?

土壤墒情检测站是一种专门用于监测土壤水分状况和土壤水力性质的设备。它由多个传感器和数据采集单元组成,能够实时监测土壤中的水分含量、土壤温度等参数,并收集和记录相关的数据,提供土壤墒情(即土壤水分状态)的详细…

|行业洞察·趋势报告|《2024旅游度假市场简析报告-17页》

报告的主要内容解读: 居民收入提高推动旅游业发展:报告指出,随着人均GDP的提升,居民的消费能力增强,旅游需求从传统的观光游向休闲、度假游转变,国内人均旅游消费持续增加。 政府政策促进旅游市场复苏&…

代码随想录——移除元素(Leetcode27)

题目链接 暴力&#xff1a;&#xff08;没有改变元素相对位置&#xff09; class Solution {public int removeElement(int[] nums, int val) {int len nums.length;for(int i 0; i < len; i){if(nums[i] val){for(int j i 1; j < len; j){nums[j-1] nums[j];}i…

C#自定义最大化、最小化和关闭按钮

目录 1.资源文件 2.读取资源文件中的图片 3.WindowState属性 4. 示例 用户在制作应用程序时&#xff0c;为了使用户界面更加美观&#xff0c;一般都自己设计窗体的外观&#xff0c;以及窗体的最大化、最小化和关闭按钮。本例通过资源文件来存储窗体的外观&#xff0c;以及最…

【设计模式】中介者模式的应用

文章目录 1.概述2.中介者模式的适用场景2.1.用户界面事件2.2.分布式架构多模块通信 3.总结 1.概述 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为型设计模式&#xff0c;它用于解决对象间复杂、过度耦合的问题。当多个对象&#xff08;一般是两个以上的对象&…

腾讯云邮件推送功能有哪些?如何有效使用?

腾讯云邮件推送如何设置&#xff1f;怎么用邮件推送做高效营销&#xff1f; 腾讯云作为业界领先的云服务提供商&#xff0c;其邮件推送功能在便捷性、稳定性和安全性上都有着出色的表现。那么&#xff0c;腾讯云邮件推送功能究竟有哪些呢&#xff1f;让AokSend来探个究竟。 腾…

map与set容器常见操作详解(含示例代码及注意事项)

&#x1f389;个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名乐于分享在学习道路上收获的大二在校生 &#x1f648;个人主页&#x1f389;&#xff1a;GOTXX &#x1f43c;个人WeChat&#xff1a;ILXOXVJE &#x1f43c;本文由GOTXX原创&#xff0c;首发CSDN&…

类与对象中C++

加油&#xff01;&#xff01;&#xff01; 文章目录 前言 一、类的6个默认成员函数 ​编辑 二、构造函数 1.概念 三、析构函数 1.概念 2.特性 四、拷贝构造函数 1.概念 2.特征 拷贝构造函数典型调用场景 五、赋值运算符重载 1.运算符重载 2.赋值运算符重载 赋值运算符重载格式…

【Qt】:坐标

坐标 一.常用快捷键二.使用帮助文档三.Qt坐标体系1.理论2.代码 一.常用快捷键 注释&#xff1a;ctrl / • 运⾏&#xff1a;ctrl R • 编译&#xff1a;ctrl B • 字体缩放&#xff1a;ctrl ⿏标滑轮 • 查找&#xff1a;ctrl F 比特就业课 • 整⾏移动&#xff1a;ctrl …

【Linux】体验一款开源的Linux服务器运维管理工具

今天为大家介绍一款开源的 Linux 服务器运维管理工具 - 1panel。 一、安装 根据官方那个提供的在线文档&#xff0c;这款工具的安装需要执行在线安装&#xff0c; # Redhat / CentOScurl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start…

.NET CORE使用Redis分布式锁续命(续期)问题

结合上一期 .NET CORE 分布式事务(三) DTM实现Saga及高并发下的解决方案(.NET CORE 分布式事务(三) DTM实现Saga及高并发下的解决方案-CSDN博客)。有的小伙伴私信说如果锁内锁定的程序或者资源未在上锁时间内执行完&#xff0c;造成的使用资源冲突&#xff0c;需要如何解决。本…

原创度检测工具分享,文章质量检测方便又简单

文章检测有利于我们了解文章内容的质量高低&#xff0c;而在以往我们检测文章只能依靠手动去检测&#xff0c;这是相当消耗工作时间的&#xff0c;但是在原创度检测工具出来之后&#xff0c;很多人开始检测文章质量就改用原创度检测工具了&#xff0c;因为使用原创度检测工具是…

ES学习日记(三)-------第三方插件选择

前言 在学习和使用Elasticsearch的过程中&#xff0c;必不可少需要通过一些工具查看es的运行状态以及数据。如果都是通过rest请求&#xff0c;未免太过麻烦&#xff0c;而且也不够人性化。 目前我了解的比较主流的插件就三个,head,cerebor和elasticHD 1.head 老牌插件,功能…

vant checkbox 复选框 样式改写

修改前 修改后 基于 vant&#xff1a; 4.8.3 unocss: 0.53.4 <van-checkbox-group v-model"query.zczb" shape"square" class"text-16 w-100% flex flex-wrap"><template v-for"item in registerCapitalOption"><v…

伪原创文章生成软件:自媒体文章写作好神器

自媒体的红利时代&#xff0c;许多人都纷纷参于其中&#xff0c;而文章写作是做自媒体的基本技能&#xff0c;但是随着技术的发展&#xff0c;如今&#xff0c;既使不会写作能力一样可以做起自媒体&#xff0c;方法就是利用伪原创文章生成软件来做内容的输出&#xff0c;其实伪…