Java锁的策略

White graces:个人主页

🙉专栏推荐:Java入门知识🙉

🙉 内容推荐:<多线程案例(线程池)>🙉

🐹今日诗词:"你我推心置腹, 岂能相负"🐹


目录

锁的策略

乐观锁和悲观锁

轻量级锁和重量级锁

自旋锁和挂起等待锁

自适应锁(synchronized)

普通互斥锁和读写锁

公平锁和非公平锁

可重入锁和不可重入锁

synchronized是哪种类型的锁

mutex是哪种类型的锁

synchronized内部工作原理

1. 偏向锁阶段

2.  轻量级锁阶段

3.重量级锁阶段

锁消除

锁粗化

小结

 CAS

原子类

CAS的ABA问题

美图分享


⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏

⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏


锁的策略

锁策略有很多种,大致分为:

1. 乐观锁和悲观锁

2. 轻量级锁和重量级锁

3. 自旋锁和挂起等待锁

4. 自适应锁

5. 普通互斥锁和读写锁

6. 公平锁和非公平锁

乐观锁和悲观锁

乐观锁: 在加锁之前进行预估, 如果预估锁冲突的概率很小, 加锁时就不会进行太多操作

悲观锁: 预估锁冲突概率很大, 加锁的操作就会很复杂,防止代码出错

乐观锁加锁过程做的操作较少,因此加锁速度可能比较快,但是可能容易出现错误

悲观锁加锁操作比较多, 加锁速度较慢,但是不容易出错

轻量级锁和重量级锁

和乐观锁和悲观锁不同的是: 轻量级和重量级是对加锁之后,对加锁结果的评价

轻量级锁: 加锁速度快,开销小就是轻量级锁, 一般也叫乐观锁

重量级锁: 加锁速度慢,开销大就是重量级锁, 一般也叫悲观锁

自旋锁和挂起等待锁

自旋锁和挂起等待锁就是轻量级锁和重量级锁的典型实现

自旋锁: 加锁的时候搭配一个循环,循环执行的过程就是自旋, ,自旋检测到其他线程释放锁时,第一时间就会加上锁,没有就进行下一次循环. 如果一直循环,就会长时间占用CPU资源, 因此自旋锁比较适用于锁冲突较少的情景, 是一种乐观锁

挂起等待锁: 当加锁线程特别多时, 如果使用自旋锁, 长时间循环,会浪费CPU资源, 如果此时让他挂起等待, 把CPU资源让出来, 因此挂起等待锁是一个悲观锁, 适用于锁冲突比较激烈的情景, 当挂起等待时,内核调度器会介入,这里的操作会比较多,真正获取到锁花的时间也会更多

自适应锁(synchronized)

synchronized可以对锁冲突进行评估,选择最合适的锁策略, 因此也叫做自适应锁

普通互斥锁和读写锁

普通互斥锁: 就是synchronized的加锁,解锁

读写锁: 分成加读锁和加写锁

加读锁: 一个线程加锁和读锁时, 另一个线程只能读锁, 不能写锁

加写锁: 一个线程加锁和写锁时, 另一个线程既不能读锁, 也不能写锁

公平锁和非公平锁

公平锁: 遵循先来后到, 排在最前面的线程最先获取加锁资格

非公平锁: 线程加锁顺序是随机的, 为非公平锁

下面这个图很形象

可重入锁和不可重入锁

概念: 对同一个线程加锁两次不会死锁, 反之则是不可重入锁

synchronized是哪种类型的锁

1. 乐观锁/悲观锁自适应

2. 轻量级锁/重量级锁自适应

3. 自旋锁/挂起等待锁自适应

4. 不是读写锁

5. 非公平锁

6. 可重入锁 看     

mutex是哪种类型的锁

mutex是Linux中的锁

1. 悲观锁

2. 重量级锁

3. 挂起等待锁

4. 不是读写锁

5. 非公平锁

6. 不可重入锁

synchronized内部工作原理

当对象执行到synchronized时, 如果对象处于未加锁的状态时,会分成三个阶段执行

1. 偏向锁阶段

2. 轻量级锁阶段

3. 重量级锁阶段

1. 偏向锁阶段

核心思想: 懒汉模式, 能不加锁就不加锁, 能晚加锁就晚一点加锁

偏向锁并没有加锁, 只是做了一个标记, 如果没有其他线程来竞争这个锁, 不加锁可以大幅度提高代码执行效率, 如果有其他线程想加锁, 就会提前抢在这个线程之前加锁, 总的来说就是非必要不加锁.

注意: 对象首次加锁先进入偏向锁, 如果没有锁竞争, 下次加锁还是先进入偏向锁, 

如果出现锁竞争了, 就会进入轻量级锁, 并且下次加锁时跳过偏向锁阶段, 直接进入轻量级锁阶段

2.  轻量级锁阶段

synchronized内部会统计有多少个线程参与对这个锁对象的竞争, 根据这个进一步区分轻量级锁和重量级锁

轻量级锁阶段就是: 线程之间有竞争, 但是不多, 轻量级锁一般通过自旋锁实现

优势: 其他线程释放锁, 自旋锁能够第一时间获取到锁

坏处: 内部一直循环比较消耗CPU

对于自旋锁来说, 如果同一个锁对象竞争者很多, 大量线程都在自旋, 这时候CPU开销就会非常大, 需要考虑升级为自旋锁

3.重量级锁阶段

重量级锁, 不会让线程自旋了, 而是阻塞等待, 把CPU资源让出来, 当线程释放锁时, 系统就会随机唤醒一个线程进行加锁

锁消除

也是synchronized内部一种优化方式, 代码编译过程中, 如果发现不需要加锁, 编译器就会直接把锁给干掉

锁粗化

编译器会把一些细粒度的锁合并成一个粗粒度的锁

细粒度: synchronized () {  }, 一般情况下, 大括号里的代码越少, 细粒度越高.

细粒度高的好处: 由于代码少执行速度较快, 加锁解锁的速度也快, 有利于线程并发执行

细粒度高的坏处: 频繁的加锁解锁可能会造成线程阻塞

有些情况下还是希望锁粗粒度更好, 比如职场工作中, 你做完一个任务就去打电话给领导汇报一下成果, 又做完一个任务再去打电话给领导汇报成果,反复如此, 领导就会烦, 并且你汇报的过程, 其他员工也可能在汇报成果(此时你就阻塞了), 因此你可以把多个成果合并在一起给领导进行汇报

小结

synchronized内部优化策略大致有这些

1. 锁升级: 偏向锁 -> 轻量级锁 -> 重量级锁

2. 锁消除: 自动干掉不必要的锁

3. 锁粗化: 将细粒度的锁合并成粗粒度的锁

 CAS

compare and swap ,这是一条CPU指令, 和Java关系不大, 但是面试要考

表示比较和交换, 这是一条原子指令, 安全性杠杠的,不会出现线程安全问题

原子类

Java中一些类对CAS指令进行了封装, 构成了原子类, 封装在

import java.util.concurrent.atomic这个包下面

这些类可以保证参数进行操作的原子性

最常用的莫过于AtomicInterger类了

它保证了关于int类型的数据加或者减都是原子操作

CAS的ABA问题

CAS指令是比较, 如果相等就交换, 但是根据唐妞不等式  相等 != 没改变过  直接秒了

比如: A -> B ->  A   还是相等, 但是A已经发生过改变

CAS在大多数情况下是安全的

极端情况下可能会出一些问题: 比如银行取款, 取款按钮用户可能会多按几下,

这是系统就会有很多扣款请求

这种情况其实挺常见的,比如电梯按钮,很多人就会狂按

具体执行流程如下:

但是扣款过程中有人向账户里转入500块呢

执行流程:

这种情况非常苛刻, 用户连续点击多次,取钱的时正好有人转入, 并且转入金额和取出金额相同

账户余额只是一个数字可加可减, 我们引入一个只能加不能减的版本号, 通过判断版本号来选择执行操

美图分享


✨🎆谢谢你的阅读和耐心!祝愿你在编程的道路上取得更多的成功与喜悦!"🎆✨🎄

⭐️点赞收藏加关注,学习知识不迷路⭐️

🎉✔️💪🎉✔️💪🎉✔️💪🎉✔️💪🎉

👍😏⛳️点赞☀️收藏⭐️关注😏👍

👍😏⛳️点赞☀️收藏⭐️关注😏👍

👍😏⛳️点赞☀️收藏⭐️关注😏👍

🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️

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

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

相关文章

[数据集][目标检测]森林火灾检测数据集VOC+YOLO格式362张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;362 标注数量(xml文件个数)&#xff1a;362 标注数量(txt文件个数)&#xff1a;362 标注类别…

四川音盛佳云电子商务有限公司铸就抖音电商新高度

在数字经济的浪潮中&#xff0c;抖音电商以其独特的魅力迅速崛起&#xff0c;成为新时代消费潮流的引领者。四川音盛佳云电子商务有限公司&#xff0c;作为抖音电商领域的佼佼者&#xff0c;凭借专业的团队和创新的理念&#xff0c;致力于为广大消费者提供优质、便捷的购物体验…

和可被k整除的子数组 ---- 前缀和

题目链接 题目: 分析: 补充知识 1. 同余定理: (a-b) % p 0即a-b能被p整除, > a % p b % p 2. c, java中 [负数 % 正数] 的结果是负数, 想要得到正确结果 > (a%pp)%p这道题和<和为k的子数组>类似, 利用前缀和的思想, 计算以i结尾的所有子数组, 前缀和为sum[i] …

探索编程逻辑中的“卡特牛(continue)”魔法

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;卡特牛逻辑的魅力 二、卡特牛逻辑的解析 三、卡特牛逻辑的应用实例 …

sqlserver——查询(四)——连接查询

目录 一.连接查询 分类&#xff1a; 内连接&#xff1a; 1. select ... from A&#xff0c;B &#xff1b; 2. select ..from A&#xff0c;B where ..&#xff1b; 3.select ...,... from A join B on... 4. where 与 join...on 的区别 5. where位置的先后 导语&#xff1…

每日5题Day11 - LeetCode 51 - 55

每一步向前都是向自己的梦想更近一步&#xff0c;坚持不懈&#xff0c;勇往直前&#xff01; 第一题&#xff1a;51. N 皇后 - 力扣&#xff08;LeetCode&#xff09; class Solution {public List<List<String>> solveNQueens(int n) {List<List<String>…

如果查看svn的账号和密码

一、找到svn存放目录&#xff08;本地默认存放SVN用户信息的目录为&#xff1a;C:\Users\Administrator\AppData\Roaming\Subversion\auth\svn.simple&#xff09;每个人的电脑环境不一样&#xff0c;因人而异。 如果找不到直接搜索svn.simple 二、下载密码查看工具 链接: 百…

MySQL——MySQL目录结构

MySQL安装完成后&#xff0c;会在磁盘上生成一个目录&#xff0c;该目录被称为MySQL的安装目录。在MySQL的安装目录中包含了启动文件、配置文件、数据库文件和命令文件等。 下面对 MySQL 的安装目录进行详细讲解 (1)bin 目录 : 用于放置一些可执行文件,如 mysql.exe、mysqld. …

软件设计师基础知识难点总结

软件设计师基础知识难点 I/O设备管理软件一般分为4个层次&#xff0c;如下图所示。 用户进程与设备无关的系统软件设备驱动程序中断处理程序硬件 直接查询控制 分为有无条件传送和程序查询方式&#xff0c;都需要通过CPU执行程序来查询外设的状态&#xff0c;判断外设是否准备好…

C#多维数组不同读取方式的性能差异

背景 近来在优化一个图像显示程序&#xff0c;图像数据存储于一个3维数组data[x,y,z]中&#xff0c;三维数组为一张张图片数据的叠加而来&#xff0c;其中x为图片的张数&#xff0c;y为图片行&#xff0c;Z为图片的列&#xff0c;也就是说这个三维数组存储的为一系列图片的数据…

深度解析 Spring 源码:探秘 CGLIB 代理的奥秘

文章目录 一、CGLIB 代理简介1.1 CGLIB 代理的基本原理和特点1.2 分析 CGLIB 如何通过字节码技术创建代理类 二、深入分析 CglibAopProxy 类的结构2.1 CglibAopProxy 类结构2.2 CglibAopProxy 类源码 三、CGLIB 代理对象的创建过程3.1 配置 Enhancer 生成代理对象3.2 探讨如何通…

PageHelper分页查询时,count()查询记录总数与实际返回的数据数量不一致

目录 场景简介代码判断异常情况排查原因解决 场景简介 1、使用PageHelper进行分页查询 2、最终构建PageInfo对象时&#xff0c;total与实际数据量不符 代码判断 异常情况 排查 通过对比count()查询的SQL与查询记录的SQL&#xff0c;发现是PageHelper分页查询时省去了order b…

Linux系统编程——基础IO与文件描述符(管理已打开的内存文件)

目录 一&#xff0c;文件预备 二&#xff0c;C语言文件操作函数 2.1 默认打开的三个流 2.2 写文件 2.3 读文件 2.4 再次理解当前路径 三&#xff0c;Linux操作文件系统调用 3.1 open()和close() 3.1.1 第一个参数 3.1.2 *第二个参数 3.1.3 第三个参数 3.2 write(…

(2024,基于熵的激活函数动态优化,具有边界条件的最差激活函数,修正正则化 ReLU)寻找更优激活函数

A Method on Searching Better Activation Functions 公众号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 3. 动机 4. 方法论 4.1 问题设定 4.1.1 贝叶斯错误率和信息熵 4.1.2 激活…

host修改

前言 想要修改 hosts 文件&#xff0c;您需要具有对系统文件的适当访问权限&#xff0c;并且知道如何编辑文本文件。hosts 文件是一个用于域名解析的本地文件&#xff0c;它允许您为特定的 IP 地址指定主机名。 以下是在不同操作系统中修改 hosts 文件的步骤&#xff1a; 一、…

香橙派 Kunpeng Pro 上手初体验

香橙派 Kunpeng Pro 上手初体验 目录 香橙派 Kunpeng Pro 上手初体验1.前言2.开箱3.开发板资源介绍硬件规格参数外观规格参数4.系统环境搭建系统镜像烧录ssh连接5.简单测试6.总结 1.前言 我很荣幸能收到了来自CSDN的测评邀请&#xff0c;让我有机会对香橙派最新推出的Kunpeng …

C# 使用Aspose生成和修改文档

Aspose库 C#中的Aspose库是一个强大的文件处理库&#xff0c;可以用于各种文件格式的创建、编辑、转换和操作。该库提供了丰富的功能&#xff0c;包括处理文档、电子表格、幻灯片、PDF、图像等多种文件格式&#xff0c;能够轻松实现文件的读取、写入、格式化、样式设置、数据操…

历时3周圆满结营,Sui Move HackerHouse精彩回顾

Sui 是基于第一原理重新设计和构建而成的 L1 公有链&#xff0c;旨在为创作者和开发者提供能够承载 Web3 中下一个十亿用户的开发平台。Sui 上的应用基于 Move 智能合约语言&#xff0c;并具有横向可扩展性&#xff0c;让开发者能够快速且低成本支持广泛的应用开发。 Move 是用…

Vectorworks 2024 Mac安装包下载Vectorworks 2024安装教程3D建模设计工具

安装 步骤 1&#xff0c;双击下载好的安装包&#xff0c;打开。 2&#xff0c;将G1DXHL.ldf拖到桌面上备用。 3&#xff0c;返回打开的镜像 选择install vectorworks2024 双击打开启动安装程序。电脑就90hi高腰腿疼痛和Y&Aaa9yY 4&#xff0c;输入电脑密码。 5&#xff0…

python onnx 推理yolov10

python onnx 推理yolov10 import onnxruntime as ort import cv2 import numpy as np# Class names for the COCO dataset CLASSES = ["person", "bicycle", "car", "motorcycle", "airplane"