【JavaEE初阶】深入理解不同锁的意义,synchronized的加锁过程理解以及CAS的原子性实现(面试经典题);

前言

🌟🌟本期讲解关于锁的相关知识了解,这里涉及到高频面试题哦~~~

🌈上期博客在这里:【JavaEE初阶】深入理解线程池的概念以及Java标准库提供的方法参数分析-CSDN博客

🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客

 

目录

📚️1.引言

📚️2.锁的策略

2.1乐观锁与悲观锁

2.2轻量级锁和重量级锁

2.3自旋锁和挂起等待锁

2.4普通互斥锁和读写锁

2.5公平锁和非公平锁

2.6可重入锁和不可重入锁

📚️3.synchronized的加锁过程

3.1锁升级

1.偏向锁阶段

2.轻量级锁

3.重量级锁

3.2锁消除

3.3锁粗化

📚️4.CAS的实现原理

4.1CAS的内部逻辑

4.2CAS实现线程安全

4.3CAS的原子性

📚️5.总结

📚️1.引言

    Hello!uu们小编又来啦,上期在介绍过线程池的理解后,相信大家已经对其有了更深的了解,致此多线程初阶已经完结,前面的博客也可以供大家学习,复习哟~~~

本期只要是讲解关于不同锁的不同的意义理解,例如:乐观锁和悲观锁,以及synchronized的加锁之前的操作.......那就直接开始吧!!!

📚️2.锁的策略

2.1乐观锁与悲观锁

这是锁的两种不同实现方式;

乐观锁:即加锁之前,预估在程序中的锁的冲突不大,因此在加锁的时候就不会进行太多的操作;

悲观锁: 即加锁之前,预估在程序中的锁的冲突很大,因此在加锁的时候就不会进行比较多的操作;

乐观锁的影响: 由于加锁的工作很少,所以加锁的时候就很快,但是缺点就是会造成更多的CPU资源的消耗(引入一些其他问题)

悲观锁的影响:由于加锁的时候工作比较多,所以在加锁的时候就比较满,所以此时造成的问题就很少;

2.2轻量级锁和重量级锁

轻量级锁:消耗的CPU资源多,加锁比较快=>这里理解为乐观锁;

重量级锁:消耗的CPU资源少,加锁比较慢=>这里理解为悲观锁;

这里的轻量级锁和重量级锁是加锁后对锁的一种评价,而乐观锁和悲观锁是加锁前的一种预估,这里是从两种不同的角度来描述一件事情;

2.3自旋锁和挂起等待锁

自旋锁:是轻量级锁的一种典型实现,一般搭配while循环,在加锁成功后退出循环,但是加锁不成功后,会进入循环再次尝试加锁;

挂起等待锁:是重量级锁的一种典型实现,在加锁失败后,会进入阻塞状态,直到获取到锁

自旋锁的使用:一般用于锁冲突比较小的情况,由于高速反复的尝试加锁,导致CPU的资源消耗上升,取而代之的是加锁的速度快,但是在线程多的情况下会发生“线程饿死”的问题

挂起等待锁的使用:一般用于所冲突比较大的情况,由于进入阻塞后,就是内核随机调度来进行执行,要进行的操作增加,导致加锁更慢了

synchronized锁:这里的synchronized锁具有自适应的能力的,例如在锁冲突情况比较严重的时候,这里的synchronized就是悲观锁、重量级锁、挂起等待锁.....所以这里的synchronized是根据当时的锁的冲突情况来进行自适应的~~~

2.4普通互斥锁和读写锁

普通互斥锁:即synchronized类似,只有加锁和解锁

读写锁:这里的解锁是一样的,但是在加锁的时候分为两种即“加读锁”与“加写锁”

这里的情况就是:

读锁和读锁这之间,不会出现锁的冲突

读锁和写锁这之间,会出现锁的冲突

写锁和写锁这之间,会出现锁的冲突

即一个线程加读锁的时候,另一个线程是可以“读”的,但是是不可以“写”的;

即一个现场加写锁的时候,另一个线程是不可以进行“读”和“写”的 

为什么要引入读写锁:

在线程的读的操作中,读这个操作本来就是线程安全的,但是使用synchronized任然要给这一部分要加锁,由于加锁这个操作本来就是一个低效率的操作;在读的过程中不加锁可以打打提升效率;

但是读的时候完全不加锁,可能会在读的时候进行写操作,所以这里又要加“读锁”;

2.5公平锁和非公平锁

公平锁:即等待加锁的时间越久,就应该在锁释放的时候,先加上锁(先来先到原则)

非公平死锁:即在锁释放后,获取锁的概率是一样的,存在竞争;

如下图所示:

2.6可重入锁和不可重入锁

可重入锁:即在加锁过后任然在这个线程继续进行加锁;

不可重入锁:即在加锁过后,这个线程就不能进行加锁了;

例如synchronized是一个可重入锁,但是在系统中的锁是一个不可重入锁;

可重入锁需要记录加锁的对象,以及加锁的次数;

📚️3.synchronized的加锁过程

在synchronized加锁之前会经历一下升级过程

3.1锁升级

1.偏向锁阶段

这里的偏向锁阶段的实现和之前讲解的“懒汉模式”是有一定的联系的,即非必要不加锁,但是这里的偏向锁,并不是真正意义上的加锁;

偏向锁:即一种非必要不加锁的模式,真正意义上是不加锁的,而是进行一次轻量级的标记

这里就是当没有锁进行竞争的话就会不加锁,只是轻量化标记一下,当有锁的竞争,那么这个标记的就会很快拿到锁;

偏向锁的作用: 存在锁冲突的情况下,这中锁没有提高效率,但是当没有锁的竞争后,因为只是轻量化标记,而不加锁,那么这里的效率就会得到很大的提升;

2.轻量级锁

轻量级锁:即通过自旋的方式进行实现,反复快速的进行加锁的操作

优点:在锁的释放后,能够快速的拿到并加上锁;

缺点:非常消耗CPU的资源;

这里synchronized会根据有多少个线程在参与竞争,如果比较多,那么就会升级成重量级锁;

3.重量级锁

重量级锁:即拿不到锁的线程不会进入自旋状态,而是进入阻塞状态,释放CPU资源;

最后由内核进行随机调度,从而加上锁;

3.2锁消除

锁消除:即synchronized的一种优化策略,但是比较保守;

即编译器在编译的时候优化一下两种情况:

1.不存在锁竞争,只有一个线程,那么此时就会进行锁消除

2.加锁的代码中没有涉及到成员变量的改动,只有局部变量的改动,就不需要进行加锁

3.3锁粗化

锁粗化:即讲一个细粒度的锁,转化为一个粗粒度的锁;

粒度:即在synchronized{ },这个括号里的代码越少,即粒度越细;代码越多,即粒度越粗

所谓的粒度粗化,如下图所示:

可以发现,这里频繁的加锁解锁会造成额外的时间开销,而直接一步到位可以剩下这部分的时间开销;

📚️4.CAS的实现原理

4.1CAS的内部逻辑

所谓的CAS即compare and swap,即一种比较和交换,这是一个特殊的CPU的指令

其内部伪代码:

boolean CAS(address,expectValue,swapValue){if(&address==expectValue){&address=swapValue;return true;}return false
}

 注意:这里是一段伪代码,不能进行运行,只是描述逻辑的,即先进行判断寄存器的值和地址值是否相等,相等就将另一个swap寄存器的值给地址值(内存地址值)

4.2CAS实现线程安全

CAS是CPU的一种指令,操作系统又对这个指令进行了封装,我们的Java又对操作系统的API进行了封装,那么我们就可以进行使用啦;

在之前我们在实现两个线程对count实现加法操作,需要进行加锁,但是有了CAS就可以不用进行加锁了;

代码如下:

public static AtomicInteger count=new AtomicInteger();public static void main(String[] args) throws InterruptedException {Thread t1=new Thread(()->{for (int i = 0; i <50000 ; i++) {count.getAndIncrement();}});Thread t2=new Thread(()->{for (int i = 0; i <50000 ; i++) {count.getAndIncrement();}});t1.start();t2.start();t1.join();t2.join();System.out.println("最终count的值为:"+count.get());}

这里就是通过使用原子类工具,实现了没有加锁的仍然线程安全的代码;

注意:之前的count++是三个指令,在线程的随机调度中存在不同指令的穿插的情况,导致线程安全问题,但是getandincrement本来就是一个线程安全的指令(就是一个指令),天然就具有原子性;

4.3CAS的原子性

在实现原子类的伪代码如下图所示

即起初内存中的值为value,oldvalue是寄存器中的值,进入循环,当比较成功,那么就value的值就为value+1了;

当存在随机调度的时候:

 

那么此时就会有以下操作:

第一步:执行右边线程的操作

第二步:进行随机调度走的代码

 

注意:在次比较发现内存和寄存器的值是不一样的了,此时就会进行再次读取内存,在次进行循环比较,发现一样了,就会加1跳出循环

代价:这里的代价,就是while循环造成的自旋,CPU的消耗;

📚️5.总结

💬💬本期小编讲解了关于不同锁的基本概念,包括我们经常使用synchronized的加锁过程包含的“锁升级,锁消除,锁粗化”的一系列的操作,以及CAS的实现和我们之前线程安全的代码的举例,本篇主要是涉及到(关于锁面试题)~~~

🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!

 


💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。

                             😊😊  期待你的关注~~~

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

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

相关文章

cdga|信息差不再是障碍:数据治理新策略

在信息爆炸的时代&#xff0c;数据已成为企业最宝贵的资产之一&#xff0c;其有效管理和利用直接关系到企业的竞争力和创新能力。然而&#xff0c;随着数据量的激增和数据来源的多样化&#xff0c;信息差——即不同部门、团队或个人之间数据理解、获取与利用上的差异&#xff0…

纠删码参数自适应匹配问题ECP-AMP实验方案(二)

6.方法设计 6.1.数据获取 为了收集不同的文件大小和纠删码参数对性能指标的影响&#xff0c;本文在Hadoop平台上进行了模拟实验。Hadoop是一种开源的分布式存储和计算框架&#xff0c;它可以支持不同类型的纠删码&#xff0c;并提供了一些应用程序接口和工具来测试和评估纠删…

美畅物联丨视频汇聚从“设”开始:海康威视摄像机设置详解

在运用畅联云平台进行视频汇聚与监控管理时&#xff0c;海康威视的安防摄像机凭借其卓越的性能与广泛的应用兼容性&#xff0c;成为了众多用户的首选产品。海康威视摄像机参数设置与调试对于实现高效的安防监控至关重要。今天&#xff0c;让我们一同深入学习海康摄像机的参数设…

无人机在矿业领域的应用!

矿区测绘与建模 无人机可以快速、全面地获取矿区的地形地貌数据&#xff0c;生成高精度的二维或三维模型。 这些模型可用于矿区的规划、设计、监测和管理&#xff0c;提高矿山的生产效率。 库存量量化监测 无人机能够捕捉厘米级的地形数据&#xff0c;通过计算得出准确的库…

【星汇极客】STM32 HAL库各种模块开发之DHT11模块

前言 本人是一名嵌入式学习者&#xff0c;在大学期间也参加了不少的竞赛并获奖&#xff0c;包括&#xff1a;江苏省电子设计竞赛省一、睿抗机器人国二、中国高校智能机器人国二、嵌入式设计竞赛国三、光电设计竞赛国三、节能减排竞赛国三等。 暑假的时候参加了太多的比赛&#…

查找满足条件的行

有 2022 年 1 月的日销售额统计表如下所示&#xff1a; 找出日销售额大于 1000 的日销售数据&#xff1a; spl("E(?1).select(Sales>1000)",A1:B32) 帮你早下班系列题目合集 免费课程学习、免费软件下载试用

图像去雾-图像去雨(matlab/python代码+教程)

看到许多小伙伴想进行图像去雨&#xff0c;图像去雾的任务&#xff0c;由于以前进行了此类项目&#xff0c;所以在此书写博客进行交流。 去雨前言 从静止图像中去除雨水是一项复杂且具有挑战性的任务。雨滴仅影响图像的很小区域&#xff0c;因此导致确定应考虑哪个区域和不应…

杭州悦数参与制定的图技术国家标准项目进入公示期!

9 月 27 日&#xff0c;由全国智能计算标准化工作组归口&#xff0c;杭州悦数科技有限公司等多家知名企业及科研机构共同参与的 《智能计算 图计算性能测试方法》 国家标准项目正式进入公示期。作为第一个图技术相关的国家标准&#xff0c;这一里程碑式的进展&#xff0c;不仅标…

win11 关掉夸克网盘的自启

1、先打开夸克的设置&#xff1a; 打开后&#xff0c;发现并没有自启动项。 2、打开win11自启动&#xff0c;然后去掉即可&#xff1a; 3、通过上面的设置&#xff0c;再次启动&#xff0c;应该是不会显示夸克了。

comfyUI如何入门?comfyUI保姆级入门攻略!

前言 配置要求 一张NVIDIA显卡最好&#xff0c;体验的话一台电脑就可以了&#xff0c; 安装步骤 访问官网:https://github.com/comfyanonymous/ComfyUI,看官网的操作步骤来。 有俩种安装window方式 1.第一种直接下载exe文件进行安装&#xff0c;点击上图的7-zip根据自已的w…

Cannon-ES中RigidVehicle的创建与应用:结合Three.js实现车辆动态模拟

本文目录 前言1、RigidVehicle1.1 概念1.2 RigidVehicle的创建与使用1.3 RigidVehicle的特性与应用 2、前置代码准备2.1 代码2.2 效果 3、RigidVehicle结合three的使用3.1 代码3.1.2 效果 3.2 控制车子移动3.2.1 效果 4、完整代码 前言 在物理引擎与三维图形渲染技术日益融合的…

Unity UndoRedo(撤销重做)功能

需求 撤销与重做功能 思考 关于记录的数据的两点思考&#xff1a; 记录操作记录影响显示和逻辑的所有数据 很显然这里就要考虑取舍了&#xff1a; 记录操作 这种方案只需要记录每一步的操作&#xff0c;具体这个操作要怎么渲染和实现出来完全需要自己去实现&#xff0c;这…

不宜使用Selenium自动化的10个测试场景

尽管在很多情况下测试自动化是有意义的&#xff0c;但一些测试场景是不应该使用自动化测试工具的&#xff0c;比如Selenium、WebDriver。 下面有10个示例&#xff0c;来解释为什么自动化在这种情况下使用时没有意义的&#xff0c;我还将为您提供每种方法的替代方法。 01.验证…

计算机毕业设计 | SpringBoot+vue 学生成绩课程管理 教务管理系统(附源码)

1&#xff0c;项目背景 教育需求增长 随着社会的发展&#xff0c;对于教育质量的要求也在不断提高。传统的手工操作和纸质记录已经不能满足现代教学的需求。因此&#xff0c;一个自动化、数字化的教务管理系统成为了必然的选择。 信息化趋势 现代科技的飞速发展使得信息化成为…

通过Dockerfile 安装rabbitMq

一、编写Dockerfile Dockerfile 指令详细注释如下&#xff1a; # 使用带有管理插件的官方 RabbitMQ 镜像作为基础 FROM rabbitmq:3.9-management# 复制自定义模板文件到 RabbitMQ 管理插件的模板目录 # 这里假设 ./users.ejs 和 ./limits.ejs 是用于自定义管理界面的模板文件…

七、InnoDB数据存储结构

文章目录 1. 数据库的存储结构:页1.1 磁盘与内存交互基本单位:页1.2 页结构概述1.3 页的大小1.4 页的上层结构2. 页的内部结构2.1 第1部分:File Header(文件头部)和 File Trailer(文件尾部)2.1.1 File Header(文件头部)2.1.2 File tRAILER(文件尾部)2.2 第2部分:Fr…

网络知识点之—EVPN

EVPN&#xff08;Ethernet Virtual Private Network&#xff09;是下一代全业务承载的VPN解决方案。EVPN统一了各种VPN业务的控制面&#xff0c;利用BGP扩展协议来传递二层或三层的可达性信息&#xff0c;实现了转发面和控制面的分离。 EVPN解决传统L2VPN的无法实现负载分担、…

【优选算法】--- 分治 快速排序

分治 快速排序 一、颜色分类 / 对快排的复习1、题目解析2、算法原理3、代码 二、排序数组&#xff08;快排的方法&#xff09;1、题目解析2、算法原理3、代码 三、数组中的第K个最大元素1、题目解析2、算法原理3、代码 四、库存管理 III&#xff08;原&#xff1a;剑指 Offer .…

如何使用pymysql和psycopg2连接MySQL和PostgreSQL数据库

在现代软件开发中&#xff0c;数据库是存储和管理数据的核心组件。Python作为一种流行的编程语言&#xff0c;提供了多种方式来连接和操作数据库。在这篇文章中&#xff0c;我们将探讨如何使用pymysql和psycopg2这两个库来连接MySQL和PostgreSQL数据库。我们将从基础概念开始&a…

Khronos:动态环境下时空度量语义SLAM的统一方法

Khronos: A Unified Approach for Spatio-Temporal Metric-Semantic SLAM in Dynamic Environments 原文 项目 引言&#xff1a; 人类居住环境通常是高度动态的&#xff0c;人、机器人和其他实体不断移动、互动和改变场景。对于机器人在这种情况下的操作&#xff0c;仅仅建立一…