当前位置: 首页 > news >正文

【多线程】常见的锁策略

请添加图片描述

✨个人主页:bit me👇
✨当前专栏:Java EE初阶👇
✨每日一语:老当益壮,宁移白首之心;穷且益坚,不坠青云之志。

目 录

  • 🏳️一. 乐观锁 vs 悲观锁
  • 🏴二. 普通的互斥锁 vs 读写锁
  • 🏁三. 重量级锁 vs 轻量级锁
  • 🚩四. 自旋锁 vs 挂起等待锁
  • 🏳️‍🌈五. 公平锁 vs 非公平锁
  • 🏴‍☠️六. 可重入锁 vs 不可重入锁

锁策略:加锁的时候咋加的


🏳️一. 乐观锁 vs 悲观锁

  • 悲观锁总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。
  • 乐观锁假设数据一般情况下不会产生并发冲突,所以在数据进行提交更新的时候,才会正式对数据是否产生并发冲突进行检测,如果发现并发冲突了,则让返回用户错误的信息,让用户决定如何去做。

Synchronized 就既是一个悲观锁,也是一个乐观锁,是一种自适应锁。当前锁冲突概率不大,以乐观锁方式运行,往往是纯用户态执行的,一旦发现锁冲突概率大了,以悲观锁的方式运行,往往要进入内核,对当前线程进行挂起等待。


🏴二. 普通的互斥锁 vs 读写锁

多线程之间,数据的读取方之间不会产生线程安全问题,但数据的写入方互相之间以及和读者之间都需要进行互斥。如果两种场景下都用同一个锁,就会产生极大的性能损耗。所以读写锁因此而产生。

  • Synchronized就属于普通的互斥锁,两个加锁操作之间会发生竞争
  • 读写锁,把加锁操作细化了,加锁分成了 “加读锁” “加写锁”。

读写锁(readers-writer lock),看英文可以顾名思义,在执行加锁操作时需要额外表明读写意图,复数读者之间并不互斥,而写者则要求与任何人互斥。

一个线程对于数据的访问, 主要存在两种操作: 读数据 和 写数据.

  • 两个线程都只是读一个数据, 此时并没有线程安全问题. 直接并发的读取即可.
  • 两个线程都要写一个数据, 有线程安全问题.
  • 一个线程读另外一个线程写, 也有线程安全问题.

读写锁就是把读操作和写操作区分对待. Java 标准库提供了 ReentrantReadWriteLock 类, 实现了读写锁.

  • ReentrantReadWriteLock.ReadLock 类表示一个读锁. 这个对象提供了 lock / unlock 方法进行加锁解锁.
  • ReentrantReadWriteLock.WriteLock 类表示一个写锁. 这个对象也提供了 lock / unlock 方法进行加锁解锁.

其中,

  • 读加锁和读加锁之间, 不互斥.
  • 写加锁和写加锁之间, 互斥.
  • 读加锁和写加锁之间, 互斥.

注意, 只要是涉及到 “互斥”, 就会产生线程的挂起等待. 一旦线程挂起, 再次被唤醒就不知道隔了多久了.
 
因此尽可能减少 “互斥” 的机会, 就是提高效率的重要途径

读写锁特别适合于 “频繁读, 不频繁写” 的场景中


🏁三. 重量级锁 vs 轻量级锁

锁的核心特性 “原子性”, 这样的机制追根溯源是 CPU 这样的硬件设备提供的.

  • CPU 提供了 “原子操作指令”.
  • 操作系统基于 CPU 的原子指令, 实现了 mutex 互斥锁.
  • JVM 基于操作系统提供的互斥锁, 实现了 synchronized 和 ReentrantLock 等关键字和类.

重量级锁锁开销比较大,做的工作比较多。

  • 大量的内核态用户态切换
  • 很容易引发线程的调度

主要是依赖了 操作系统 提供的锁,使用这种锁,就容易产生阻塞等待。

轻量级锁锁开销比较小,做的工作比较少。

  • 少量的内核态用户态切换.
  • 不太容易引发线程调度

主要尽量避免使用 操作系统 提供的锁,而是尽量在用户态来完成功能,尽量避免 用户态 和 内核态 的切换,尽量避免挂起等待。

synchronized 是自适应锁,也是一个轻量级锁. 如果锁冲突比较严重, 就会变成重量级锁。


🚩四. 自旋锁 vs 挂起等待锁

  • 自旋锁:是轻量级锁的具体实现
  • 挂起等待锁:是重量级锁的具体实现

自旋锁是轻量级锁,也是乐观锁
挂起等待锁是重量级锁,也是悲观锁

按之前的方式,线程在抢锁失败后进入阻塞状态,放弃 CPU,需要过很久才能再次被调度。但实际上, 大部分情况下,虽然当前抢锁失败,但过不了很久,锁就会被释放。没必要就放弃 CPU. 这个时候就可以使用自旋锁来处理这样的问题。自旋锁发现锁冲突的时候,不会挂起等待,会迅速再来尝试看这个锁能不能获取到

自旋锁伪代码:

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

自旋锁特点:

  1. 一旦锁被释放,就可以第一时间获取到
  2. 如果锁一直不释放,就会消耗大量的 CPU

挂起等待锁特点:

  1. 一旦锁被释放,不能第一时间获取到
  2. 在锁被其他线程占用的时候,会放弃 CPU 资源

synchronized 作为轻量级锁的时候,内部是自旋锁,作为重量级锁的时候,内部是挂起等待锁。


🏳️‍🌈五. 公平锁 vs 非公平锁

啥样的情况才算公平?
 
认为符合 “先来后到” 这样的规则,就是公平

公平锁:遵守 “先来后到”. B 比 C 先来的. 当 A 释放锁的之后, B 就能先于 C 获取到锁.

非公平锁:不遵守 “先来后到”. B 和 C 都有可能获取到锁.

注意:

  • 操作系统内部对于挂起等待锁,就是非公平的(没有考虑先来后到),如果想要使用公平锁就要搞额外的数据结构来进行控制实现
  • 公平锁和非公平锁没有好坏之分, 关键还是看适用场景

synchronized 是非公平锁


🏴‍☠️六. 可重入锁 vs 不可重入锁

可重入锁的字面意思是“可以重新进入的锁”,即允许同一个线程多次获取同一把锁。

Java里只要以Reentrant开头命名的锁都是可重入锁,而且JDK提供的所有现成的Lock实现类,包括 synchronized 关键字锁都是可重入的。

理解 “把自己锁死”

private static void func(){//第一次加锁synchronized (Demo26.class){//第二次加锁synchronized (Demo26.class){//...}}
}

按照之前对于锁的设定,第二次加锁的时候,就会阻塞等待,要等到第一次锁释放,这里的第二次加锁才能成功,但是第一次加锁释放不了,得第二次加锁成功代码继续往下走,才能走到第一次加锁的释放代码。

这就是个 “死锁!”。第二个锁加锁成功,依赖于第一个锁释放;第一个锁释放又依赖第二个锁加锁成功。

为了避免上述情况,就引入了 “可重入锁”,一个线程,可以对同一个锁,反复加锁多次,也没事!

可重入锁,在内部记录了这个锁是哪个线程获取到的,如果发现当前加锁的线程和持有锁的线程是同一个,则不挂起等待,而是直接获取到锁。同时还会给锁内部加上个计数器,记录当前是第几次加锁了,通过计数器来控制啥时候释放锁。

synchronized 也是可重入锁

相关文章:

【多线程】常见的锁策略

✨个人主页:bit me👇 ✨当前专栏:Java EE初阶👇 ✨每日一语:老当益壮,宁移白首之心;穷且益坚,不坠青云之志。 目 录🏳️一. 乐观锁 vs 悲观锁🏴二. 普通的互斥…...

如何让虚拟机里的Ubuntu通过连接手机USB数据线上网

目录 一 前言 二 Windows联网方法 三 Ubuntu联网方法 一 前言 最近遇到了这样一个问题,有一台台式机,地插网口无法访问外网,周边也没有无线路由器,要访问外网,该如何做?进一步的,这台台式机…...

windows渗透(sam、system文件导出)

通过本地PC中渗透测试平台Kali对服务器场景Windows进行系统服务及版本扫描渗透测试,并将该操作显示结果中Telnet服务对应的端口号作为FLAG提交;通过本地PC中渗透测试平台Kali对服务器场景Windows进行系统服...

b01lers(php.galf)

目录 前文 正文 前文 <?phpclass A{public $codeNULL;public $argsNULL;public function __construct($code,$argsNULL){$this->code$code;$this->args$args;print_r("2333") ;} public function __invoke($code,$args){echo $code;print_r("执行inv…...

记一次若依后台管理系统渗透

前言 最近客户开始hw前的风险排查&#xff0c;让我们帮他做个渗透测试&#xff0c;只给一个单位名称。通过前期的信息收集&#xff0c;发现了这个站点&#xff1a; 没有验证码&#xff0c;再加上这个图标&#xff0c;吸引了我注意&#xff1a; 从弱口令开始 若依默认口令为ad…...

Mybatis(四):自定义映射resultMap

自定义映射resultMap前言一、处理字段和属性的映射关系问题&#xff1a;方案一&#xff1a;使用别名方案二&#xff1a;在mybatis-config.xml中设置mapUnderscoreToCamelCase方案三&#xff1a;在映射文件中设置redultMap二、多对一映射处理问题&#xff1a;方案一&#xff1a;…...

机器学习---降维算法

知其然知其所以然【写在前面】主成分分析&#xff08;PCA&#xff09;原理部分代码部分可视化部分线性判别分析&#xff08;LDA&#xff09;原理部分代码部分可视化部分独立成分分析&#xff08;ICA&#xff09;原理部分代码部分可视化部分t-SNE降维算法原理部分代码部分可视化…...

【Vue2从入门到精通】详解Vue.js的15种常用指令及其使用场景

文章目录前言1. v-text / {{ expression }}2.v-html3.v-bind4.v-on5. v-model6.v-for7.v-if / v-else-if / v-else9.v-show10.v-cloak11.v-pre12.组件注册指令13.动态组件指令14.自定义指令15.过滤器指令前言 Vue.js 是一款流行的前端框架&#xff0c;它通过指令&#xff08;Di…...

数据库知识总结

数据库知识点总结个人向。 目录第一章 绪论第二章 关系数据库第三章 关系数据库标准语言SQL第四章 数据库安全性第五章 数据库完整性第六章 关系数据理论第七章 数据库设计第十章 数据库恢复技术第十一章 并发控制第一章 绪论 数据(data): 描述事物的符号记录。 数据库(DataB…...

处理数组循环中删除元素导致索引错位情况

就是很多时候我们对一个数组进行操作的时候&#xff0c;在for遍历的过程中删掉了一个元素&#xff0c;那么在删掉那个元素之后的所有元素的索引值都会减少一位&#xff0c;数组长度缩短一位&#xff0c;删完之后&#xff0c;正在进行的循环会继续循环下去&#xff0c;但是循环的…...

快速排序,分治法实际应用(含码源与解析)

&#x1f38a;【数据结构与算法】专题正在持续更新中&#xff0c;各种数据结构的创建原理与运用✨&#xff0c;经典算法的解析✨都在这儿&#xff0c;欢迎大家前往订阅本专题&#xff0c;获取更多详细信息哦&#x1f38f;&#x1f38f;&#x1f38f; &#x1fa94;本系列专栏 -…...

linux入门---操作体统的概念

什么是操作系统 操作系统是一个对软硬件资源进行管理的软件。计算机由一堆硬件组成&#xff0c;这些硬件遵循着冯诺依曼体系结构 在这个硬件的基础上还有一个软件叫做操作系统 操作系统的任务是对硬件进行管理&#xff0c;既然是管理的话操作系统得访问到底层的硬件&#xf…...

《Qt 6 C++开发指南》提供4个版本的示例程序

《Qt 6 C开发指南》包含丰富的示例项目&#xff0c;为了方便读者使用《Qt 6 C开发指南》学习Qt编程&#xff0c;本书提供了4个版本的示例程序。读者可在人民邮电出版社异步社区本书的配套资源&#xff08;如图1&#xff09;里下载这4个版本的示例程序。图1 异步社区本书配套资源…...

chartgpt 告诉我的,loss 函数的各种知识

一、libtorch中常见的损失函数及其使用场景的总结1. CrossEntropyLoss:CrossEntropyLoss&#xff08;交叉熵损失&#xff09;主要用于分类任务。它适用于多分类问题&#xff0c;其中每个样本只属于一个类别&#xff08;互斥&#xff09;。该损失函数将预测概率与真实标签的one-…...

旅行推销员问题的遗传算法中的完整子路线顺序交叉

摘要 旅行商问题&#xff08;TSP&#xff09;是许多著名的组合问题之一。TSP可以解释为很难找到从第一个城市出发&#xff0c;经过所有城市&#xff0c;然后返回起点的最短距离。在标准问题中&#xff0c;TSP通常用于确定新算法的效率。遗传算法是求解TSP问题的一种成功算法。…...

Python实现词频统计

词频统计是自然语言处理的基本任务&#xff0c;针对一段句子、一篇文章或一组文章&#xff0c;统计文章中每个单词出现的次数&#xff0c;在此基础上发现文章的主题词、热词。 1. 单句的词频统计 思路&#xff1a;首先定义一个空字典my_dict&#xff0c;然后遍历文章&#xf…...

微信小程序面试题(day08)

文章目录微信小程序自定义组件的使用&#xff1f;微信小程序事件通道的使用&#xff1f;微信小程序如何使用vant组件库&#xff1f;微信小程序自定义组件父传子子传父&#xff1f;微信小程序自定义组件生命周期有哪些&#xff1f;微信小程序授权登录流程&#xff1f;web-view。…...

最强的Python可视化神器,你有用过么?

数据分析离不开数据可视化&#xff0c;我们最常用的就是Pandas&#xff0c;Matplotlib&#xff0c;Pyecharts当然还有Tableau&#xff0c;看到一篇文章介绍Plotly制图后我也跃跃欲试&#xff0c;查看了相关资料开始尝试用它制图。 1、Plotly Plotly是一款用来做数据分析和可视…...

Ubuntu使用vnc远程桌面【远程内网穿透】

文章目录1.前言2.两台互联电脑的设置2.1 Windows安装VNC2.2 Ubuntu安装VNC2.3.Ubuntu安装cpolar3.Cpolar设置3.1 Cpolar云端设置3.2.Cpolar本地设置4.公网访问测试5.结语1.前言 记得笔者刚刚开始接触电脑时&#xff0c;还是win95/98的时代&#xff0c;那时的电脑桌面刚迈入图形…...

【C++】map、set、multimap、multiset的介绍和使用

我讨厌世俗&#xff0c;也耐得住孤独。 文章目录一、键值对二、树形结构的关联式容器1.set1.1 set的介绍1.2 set的使用1.3 multiset的使用2.map2.1 map的介绍2.2 map的使用2.3 multimap的使用三、两道OJ题1.前K个高频单词&#xff08;less<T>小于号是小的在左面升序&…...

3分钟掌握Windows驱动管理的终极利器:DriverStore Explorer完全指南

3分钟掌握Windows驱动管理的终极利器&#xff1a;DriverStore Explorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 你是否曾为Windows系统越来越慢而烦恼&#xff1f;是否发…...

3分钟解锁你的QQ音乐:这款macOS工具让加密格式秒变通用音频

3分钟解锁你的QQ音乐&#xff1a;这款macOS工具让加密格式秒变通用音频 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac&#xff0c;qmc0,qmc3转mp3, mflac,mflac0等转flac)&#xff0c;仅支持macOS&#xff0c;可自动识别到QQ音乐下载目录&#xff0c;…...

AI音频转封面终极指南:3步打造专业音乐封面

AI音频转封面终极指南&#xff1a;3步打造专业音乐封面 【免费下载链接】AICoverGen A WebUI to create song covers with any RVC v2 trained AI voice from YouTube videos or audio files. 项目地址: https://gitcode.com/gh_mirrors/ai/AICoverGen 想要为你的音乐作…...

跨平台项目实战:完整UI组件库与状态管理方案

一、项目实战概述随着移动端、Web端、桌面端多终端统一开发的需求日益普及&#xff0c;跨平台开发已成为企业级项目的主流选型。传统分端开发模式存在代码冗余、迭代效率低、UI风格不统一、状态逻辑复用困难等痛点。本项目以一套代码多端适配、UI标准化、状态统一管控为核心目标…...

数据可视化库对比:选择最适合你的工具

数据可视化库对比&#xff1a;选择最适合你的工具 前言 大家好&#xff0c;我是前端老炮儿。今天咱们来聊聊数据可视化库的选择&#xff01; 在前端开发中&#xff0c;数据可视化是一个非常重要的领域。市面上有很多优秀的可视化库&#xff0c;比如ECharts、D3.js、Chart.js、T…...

0522晨间日记

# 0522晨间日记 - 关键词 - 上午- 过站的问题- 昨天有一个产品卡在母子码绑定了- 早晨的各类菜单没有同步&#xff0c;不知道怎么做。- 最终明确是&#xff1a; 因为一个产品对应2种的条码导致的卡住了- 需要在条码规则上增加多个检查对应的- 总结- 最近一周西门子遇到的问题- …...

文档下载神器kill-doc:如何快速免费下载30+平台的文档资源

文档下载神器kill-doc&#xff1a;如何快速免费下载30平台的文档资源 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档&#xff0c;但是相关网站浏览体验不好各种广告&#xff0c;各种登录验证&#xff0c;需要很多步骤才能下载文档&#xff0c;该脚本就是为…...

别再只用Selenium了!手把手教你用Python+UIAutomation+Unittest搭建Windows应用自动化测试框架

从Selenium到UIAutomation&#xff1a;Windows GUI自动化测试实战进阶指南 当Web自动化测试工程师首次接触Windows桌面应用测试时&#xff0c;往往会陷入工具选择的困境。传统基于坐标操作的自动化方案难以应对动态界面变化&#xff0c;而商业工具又存在学习成本高、灵活性不足…...

专栏导读:为什么需要从 MM 理解 HMM

一个真实的困境 假设你是一个 GPU 计算框架的开发者。用户写了这样一段代码&#xff1a; float *data malloc(1GB); // ... 填充数据 ... gpu_kernel<<<grid, block>>>(data); // 希望 GPU 直接访问 data在传统编程模型下&#xff0c;这不可能工作——GPU …...

铜钟音乐平台完整指南:三步打造纯净无干扰的听歌体验

铜钟音乐平台完整指南&#xff1a;三步打造纯净无干扰的听歌体验 【免费下载链接】tonzhon-music 铜钟 Tonzhon (tonzhon.whamon.com): 干净纯粹的音乐平台 (铜钟已不再使用 tonzhon.com&#xff0c;现在的 tonzhon.com 不是正版的铜钟) 项目地址: https://gitcode.com/GitHu…...