【JavaEE】——各种“锁”大总结

news2024/11/18 2:34:04

8e19eee2be5648b78d93fbff2488137b.png

阿华代码,不是逆风,就是我疯,

你们的点赞收藏是我前进最大的动力!!希望本文内容能够帮助到你!

目录

一:乐观锁和悲观锁

1:乐观锁

2:悲观锁

3:总结

二:轻量级锁和重量级锁

1:轻量级锁

2:重量级锁

3:总结

三:自旋锁和挂起等待锁

1:自旋锁

2:挂起等待锁

四:普通互斥锁和读写锁

1:普通互斥锁

2:读写锁

(0)知识联系

(1)此处解释

(2)总结

3:为什么引入读写锁

(1)场景一

(2)场景二

(3)优化

五:公平锁和非公平锁

1:两者对比

六:可重入锁和不可重入锁

七:synchronized自适应阶段

1:偏向锁阶段

2:轻量级锁阶段

3:重量级锁阶段

4:总结

八:锁消除

九:锁粗化

1:“粒度”

2:定义


一:乐观锁和悲观锁

1:乐观锁

在加锁过程中,预估发生锁冲突的概率小,降低加锁的工作量,加锁的效率就提高了,安全系数不高(可能会引发占用大量cpu资源的问题)

2:悲观锁

在加锁过程中,预估发生锁冲突的概率大,提升加锁的工作量,加锁的效率就下降了,但是安全系数高

3:总结

乐观锁——牺牲安全性换来效率

悲观锁——牺牲效率换来安全性

二:轻量级锁和重量级锁

引入:在乐悲观的基础上延伸出来的

1:轻量级锁

加锁的开销小,速度快——一般指乐观锁

2:重量级锁

加锁的开销大,速度慢——一般指悲观锁

3:总结

乐/悲观锁是加锁前对没有发生的事情的预估

轻/重量锁是加锁后对结果的评价

整体上来说,两者都是在对一件事情进行描述

三:自旋锁和挂起等待锁

1:自旋锁

自旋锁是轻量级锁的一种实现,也是乐观锁,通过与一个while循环搭配,如果获取到锁,那就结束循环;如果没有获取到锁,不会阻塞放弃cpu,而是继续下一次循环,直到获取到锁

(1)使用场景:锁冲突不激烈

(2)优点:其它线程一旦释放锁,就能快速获取到锁

(3)缺点:会占用消耗大量的cpu资源

2:挂起等待锁

挂起等待锁是重量级锁的一种实现,也是悲观锁,锁释放后并不能第一时间获取到锁,而是要通过操作系统的内核进行调度去获取锁,这个等待的过程时间较长。

(1)使用场景:锁冲突激烈

(2)优点:在内核调度的等待时间中,cpu可以做别的事情,即降低了cpu的资源消耗

(3)缺点:不能第一时间获取到锁

四:普通互斥锁和读写锁

1:普通互斥锁

与synchronized相似,可以进行加锁和解锁

2:读写锁

(0)知识联系

想想之前文章写到的MySQL事务处理——三读

“脏读”——给写加锁(写的时候不能读)

“不可重复读”——给读加锁(读的时候不能写)

“幻读”——读写都加上锁

(1)此处解释

读锁和读锁之间,不会发生锁冲突(不会阻塞)

写锁和写锁之间,会发生锁冲突(会阻塞)

读锁和写锁之间,会发生锁冲突(会阻塞)

(2)总结

一个线程加读锁的时候,另一个线程只能读,不能写

一个线程加写锁的时候,另一个线程只能写,不能读

3:为什么引入读写锁

(1)场景一

两个线程一起读,本身就是线程安全的不互斥,如果使用synchronized,就让两者互斥了

(2)场景二

如果一个线程读,一个线程写,也是不可以的(参考MySQL事务那一章节)

(3)优化

在实际开发中,本身读操作就是非常频繁的,引入读写锁可以大大节省下来“并发读”带来的锁冲突的资源消耗,

五:公平锁和非公平锁

1:两者对比

我们知道线程遵守“随机调度”的原则,所以在在加锁过程中就产生了“锁竞争”这一现象,在“Java”中规定公平就是遵守“先来后到”这一原则,synchronized本身就是非公平锁——一旦解锁,下一个加锁的线程是无法确定的。

所以我们引入队列,记录每个线程的顺序,依次加锁,实现“公平锁”

六:可重入锁和不可重入锁

一个线程对同一个对象加了两次锁,不会产生死锁,根据{}和内置的计数器来确定真正加锁和解锁的位置,synchronized就是可重入锁(推荐看看阿华之前写的那篇《多重入锁》文章哈)

系统自带的锁一般是不可重入锁。

七:synchronized自适应阶段

IDEA中提供的synchronized加锁具有自适应能力,内部会自动评估当前锁冲突的激烈程度,在乐观锁(系列:乐观锁,轻量级锁,自旋锁)和悲观锁(系列:悲观锁,重量级锁,挂起等待锁)中进行筛选。

这也是一种优化方式

1:偏向锁阶段

假设现在有一把偏向锁,A线程拿上了这把锁,不是真正意义上的加锁(假加锁),而是让这把锁对A线程有一个(轻量)标记,如果有其他的线程竞争也想要拿上这把锁,那A就会先一步加锁(真加锁)。

理解:

偏向锁标记是对象里头的一个属性,每个锁对象都有这么一个标记,锁对象首次被加锁都会先进入偏向锁阶段

如果没有锁竞争,那么下次加锁,还是会进入偏向锁阶段。

如果在加锁的过程中遭遇“锁竞争”,那么就会升级为“轻量级锁”阶段,

优点:非必要不加锁,没有锁竞争,偏向锁能大大提高效率

彩蛋:锁先生舔着女神A,女神A吊着锁先生就是不跟他确认关系,忽然有个姑娘B加入进来,想和锁先生确认关系,女神A就慌了~,赶快跟锁先生就确认男女朋友了,像极了爱情~~~

2:轻量级锁阶段

通过“自旋锁”的方式实现,synchronized内部也会统计有多少个线程在“锁竞争”,因为一旦超过某一个线程数量限制,大量的自旋锁会非常消耗cpu资源,此时就会升级为“重量级锁阶段”

优点:其他线程一旦释放锁,就能快速拿到锁

缺点:非常消耗cpu资源

3:重量级锁阶段

承接上文,此时线程放弃自旋锁,进入“阻塞等待”,当解锁后,系统在随机唤醒线程进行加锁。

4:总结

以上synchronized加锁的三个阶段是层层递进升级的,在目前Java中是不能够降级的,

八:锁消除

假如一个线程加了锁,但是一眼看过去这个线程肯定没有线程安全问题,那么在编译器编译代码的时候就会自动“消除锁”,提高效率。

针对一些模棱两可的代码,编译器不知道要不要加锁,统一都不会进行锁消除

九:锁粗化

1:“粒度”

synchronized{}花括号中的代码数量越少,则称锁的粒度越细;代码越多,锁的粒度越粗

2:定义

把多个细粒度的锁,合并成一个粗粒度的锁,就叫锁粗化

锁粗化也是为了提高效率,它跟可重入锁可不一样哦

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

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

相关文章

人工智能实战用折线图解读产业GDP发展态势

内容提要 项目分析项目实战 一、项目分析 1、问题提出 我们拿到一大堆关于GDP的数据,如何从这些表面看起来杂乱无章的数据中解读出一些有价值的信息呢? 显然,如果能将这些数据以图形的方式展现出来,例如将这些数据值随时间(…

备考中考的制胜法宝 —— 全国历年中考真题试卷大全

在中考这场重要的战役中,每一分都至关重要。为了帮助广大考生更好地备考,我们精心整理了这份全国历年中考真题试卷大全,旨在为大家提供最全面、最权威的备考资料。 文章目录 1. 全科覆盖,无遗漏2. 历年真题,权威可靠3.…

【微服务】springboot 实现动态修改接口返回值

目录 一、前言 二、动态修改接口返回结果实现方案总结 2.1 使用反射动态修改返回结果参数 2.1.1 认识反射 2.1.2 反射的作用 2.1.3 反射相关的类 2.1.4 反射实现接口参数动态修改实现思路 2.2 使用ControllerAdvice 注解动态修改返回结果参数​​​​​​​ 2.2.1 注解…

【C++算法】4.双指针_快乐数

文章目录 题目链接:题目描述:解法C 算法代码:图解: 题目链接: 202.快乐数 题目描述: 解法 根据题目来看,可能是无限循环,也可能是快乐数。因为就相当于下图: 无限循环可…

QT--基础

将默认提供的程序都注释上意义 0101.pro QT core gui #QT表示要引入的类库 core:核心库 gui:图形化界面库 #如果要使用其他库类中的相关函数,则需要加对应的库类后,才能使用 greaterThan(QT_MAJOR_VERSION, 4): QT wid…

AMD 矩阵核心

AMD matrix cores — ROCm Blogs 注意: 本文博客之前是 AMD lab notes 博客系列的一部分。 矩阵乘法是线性代数的一个基本方面,它在高性能计算(HPC)应用中是一个普遍的计算。自从 AMD 推出 CDNA 架构以来,广义矩阵乘法…

基于SpringBoot+Vue+MySQL的甜品店管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 在数字化浪潮的推动下,甜品店行业也面临着转型与升级的需求。传统的线下经营模式已难以满足现代消费者对于便捷、高效购物体验的追求。为了提升运营效率、优化顾客体验,我们设计了一款基于SpringBoot后端…

Django基础-创建新项目,各文件作用

学习Django的前置知识: python基本语法:需要掌握Python中的变量、循环、条件判断、函数等基本概念。面向对象编程(OOP):Django的核心架构基于面向对象编程,许多功能(如模型和视图)依…

黑神话悟空小西天

游戏里我们一开始就出现一个很可爱的小和尚,当脚步声传来,小和尚化身为一尊弥勒佛,而这尊弥勒佛的大小和位置都在说,这里没有弥勒佛的位置。 随后天命人进入一片雪地,遇到了赤尻马猴,打跑赤尻马猴&#xff…

C++_unordered系列关联式容器(哈希)

unordered系列关联式容器,我们曾在C_map_set详解一文中浅浅的提了几句。今天我们来详细谈谈 本身在C11之前是没有unordered系列关联式容器的,unordered系列与普通的map、set的核心功能重叠度达到了90%,他们最大的不同就是底层结构的不同&…

AVL树(平衡二叉树)的介绍以及相关构建

欢迎光临 : 羑悻的小杀马特-CSDN博客 目录 一AVL树的介绍: 二AVL树的实现: 1结构框架: 2节点的插入: 旋转: 21左单旋: 2.1.1左单旋介绍及步骤: 2.1.2左单旋代码实…

【JavaSE系列】IO流

目录 前言 一、IO流概述 二、IO流体系结构 三、File相关的流 1. FileInputStream 2. FileOutputStream 3. FileReader 4. FileWriter 四、缓冲流 五、转换流 1. InputStreamReader 2. OutputStreamWriter 六、数据流 七、对象流 八、打印流 九、标准输入输出流…

C++学习9.28

1> 创建一个新项目,将默认提供的程序都注释上意义 por QT core gui #QT表示引入的类库 core:核心库例如IO操作在该库中 gui:图形化显示库 #如果要使用其他类库中的相关函数,就需要调用相关类库后,才能加以使用greaterThan(Q…

c++926

1.什么是虚函数?什么是纯虚函数? 虚函数:被virtual关键字修饰的成员函数,用于实现多态性,通过基类访问派生类的函数。纯虚函数:在虚函数后面添加0,只有声明而没有实现,需要派生类提…

天龙八部怀旧单机微改人面桃花+安装教程+GM工具+虚拟机一键端

今天给大家带来一款单机游戏的架设:天龙八部怀旧单机微改人面桃花。 另外:本人承接各种游戏架设(单机联网) 本人为了学习和研究软件内含的设计思想和原理,带了架设教程仅供娱乐。 教程是本人亲自搭建成功的&#xf…

图说数集相等定义表明“R各元x的对应x+0.0001的全体=R“是几百年重大错误

黄小宁 设集A{x}表A各元均由x代表,{x}中变量x的变域是A。其余类推。因各数x可是数轴上点的坐标故x∈R变为实数yx1的几何意义可是:一维空间“管道”g内R轴上的质点x∈R(x是点的坐标)沿“管道”g平移变为点y…

红队信息搜集扫描使用

红队信息搜集扫描使用 红队行动中需要工具化一些常用攻击,所以学习一下 nmap 等的常规使用,提供灵感 nmap 帮助 nmap --help主机扫描 Scan and no port scan(扫描但不端口扫描)。-sn 在老版本中是 -sP,P的含义是 P…

视频美颜SDK与直播美颜工具API是什么?计算机视觉技术详解

今天,小编将深入探讨视频美颜SDK与直播美颜工具API的概念及其背后的计算机视觉技术。 一、视频美颜SDK的概念 视频美颜SDK是一套用于开发实时美颜效果的工具集,开发者可以利用它在视频流中实现面部特征的优化。这些SDK通常提供了一系列功能&#xff0c…

.NET 红队武器库和资源集合 (第38期)

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

计算机网络自顶向下(1)---网络基础

目录 1.网络的分类 2.网络协议 3.网络分层结构 1.OSI七层模型 2.TCP/IP四层模型 3.网络与OS的关系 4.网络传输基本流程 1.协议报头 5.网络中的地址管理 1.IP地址 2.端口号 6.传输层协议 1.TCP协议 2.UDP协议 3.网络字节序 7.socket 1.网络的分类 局域网&…