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

锁策略、原子编程CAS 和 synchronized 优化过程

前言

锁冲突:两个线程获取一把锁,一个线程阻塞等待,一个线程加锁成功。

目录

前言

一、锁策略

(一)乐观锁和悲观锁

(二)重量级锁和轻量级锁

(三)自旋锁和挂起等待锁

(四)读写锁

(五)公平锁和非公平锁

(六)可重入锁和不可重入锁

二、原子编程CAS

(一)实现原子类

(二)实现自旋锁

(三)CAS的ABA问题

三、synchronized 优化过程

结语


一、锁策略

(一)乐观锁和悲观锁

根据加锁之前对锁冲突概率的预测,预定工作的多少!

乐观锁:预测该场景中,不太出现锁冲突的情况,后续做的工作更少。

悲观锁:预测该场景中,非常容易出现锁冲突的情况,后续做的工作更多。

synchronized初始使用乐观锁策略,当发现锁竞争比较频繁时,就会自动切换成悲观锁策略。

(二)重量级锁和轻量级锁

加锁之后,考虑实际的锁的开销。

重量级锁:加锁的开销越大,花的时间越多,占用系统资源多。

轻量级锁:加锁的开销越小,花的时间越少,占用系统资源少。

synchronized开始是一个轻量级锁,如果锁冲突比较严重,就会变成重量级锁。

(三)自旋锁和挂起等待锁

自旋锁:轻量级锁的一种典型实现。在用户态下,通过自旋的方式(while循环),实现类似于加锁的效果,消耗一定的CPU资源,但可最快速度拿到锁。

挂起等待锁:重量级锁的一种典型实现。通过内核态,借助系统提供的锁机制,当出现锁冲突时,会牵扯到内核对于线程的调度,使冲突的线程出现挂起(阻塞等待),消耗的CPU资源少,但无法保证第一时间拿到锁。

synchronized中的轻量级锁策略大概是通过自旋锁实现的;

synchronized中的重量级锁策略大概是基于系统的互斥锁实现的。

(四)读写锁

将读操作和写操作分开了。如图:

synchronized不是读写锁。

(五)公平锁和非公平锁

公平锁:遵循先来后到的道理。

非公平锁:看起来概率相等,实际不公平(每个线程的阻塞时间不一样)。

synchronized是非公平锁。

(六)可重入锁和不可重入锁

可重入锁:如果一个线程争对一把锁连续加锁两次,不会出现死锁的情况。

不可重入锁:如果一个线程争对一把锁连续加锁两次,会出现死锁的情况。

synchronized是可重入锁。

二、原子编程CAS

CAS本质上是一种无锁编程,将某个寄存器中的值和内存中的值进行比较,如果相等则进行交换

(一)实现原子类

可以使用 自增/自减/自增任意值/自减任意值 实现计数、统计这类场景中。

常用的有:AtomicInteger、AtomicLong

加锁保证线程安全是通过锁避免出现穿插;但是CAS保证线程安全是借助CAS识别当前是否出现穿插的情况,如果没有穿插就是安全的,穿插了就重新读取内存的最新值,再次尝试修改。

(二)实现自旋锁

获取当前线程的引用,判断其是否进行了加锁。加锁了就自旋等待,没有加锁就将内置变量owner设为当前尝试加锁的线程。

(三)CAS的ABA问题

CAS是根据判断内存和寄存器中的值是否相等来进行判断其是否发生改变。但是如果这两者都发生了从A变成B,又从B变成了A的情况,那我们的CAS就会判断错误,从而导致A再次发生变化。

为了解决这类ABA问题,就引入了版本号,判断版本号是否相等即可

数据每修改一次,版本号就增加一次,故此原先的A和后来的A的版本号不同,判断结果也就会判断他们不同,不会使其发生改变。

三、synchronized 优化过程

synchronized不是一开始就是对我们的代码块处于进行加锁的状态。synchronized的改变是一个自适应的过程: 无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁。

偏向锁:不是真的加锁,而只是做了一个标记。如果有别的线程来竞争锁了,就会真的加锁如果没有其他线程竞争锁,就会始终都不会真的加锁

synchronized还有一些其他的优化操作

锁消除:编译器会自动的判断你当前的代码是否有必要加锁。如果你写了锁,但实际上没必要加锁就会把锁自动删掉。

锁粗化:关于“锁的粒度”。如果加锁操作里包含的实际执行语句多,就认为锁的粒度越大。


结语

这篇博客如果对你有帮助,给博主一个免费的点赞以示鼓励,欢迎各位🔎点赞👍评论收藏⭐,谢谢!!!

相关文章:

锁策略、原子编程CAS 和 synchronized 优化过程

前言 锁冲突:两个线程获取一把锁,一个线程阻塞等待,一个线程加锁成功。 目录 前言 一、锁策略 (一)乐观锁和悲观锁 (二)重量级锁和轻量级锁 (三)自旋锁和挂起等待…...

【WINAPI】文件读写操作问题

问题描述 在利用WINAPI中的WriteFile和ReadFile函数进行文件读写操作时,出现无法正常读写文件报错。 分析问题 查阅WINAPI源码,查看参数列表各个参数的数据类型。 发现其中第二个参数,也就是需要写进文件的真实数据,其数据类型…...

【LeetCode-中等题】148. 排序链表

文章目录 题目方法一:集合排序(核心是内部的排序)方法二: 优先队列(核心也是内部的排序)方法三:归并排序(带递归) 从上往下方法四:归并排序(省去递…...

Ceph EC pg backfill run

pg的backfill请求也是发送到osd的work queue中与业务IO一起竞争。 PGRecovery::run backfill 57 void PGRecovery::run( 58 OSD *osd, 59 OSDShard *sdata, 60 PGRef& pg, 61 ThreadPool::TPHandle &handle) 62 { 63 osd->do_recovery(pg.get(), epoch_queued…...

腾讯云服务器地域怎么选?广州上海北京?

腾讯云服务器地域有什么区别?怎么选择比较好?地域选择就近原则,距离地域越近网络延迟越低,速度越快。关于地域的选择还有很多因素,地域节点选择还要考虑到网络延迟速度方面、内网连接、是否需要备案、不同地域价格因素…...

Apple Configurator iphone ipad 设备管控 描述文件使用方法

一、准备 App Store 下载安装 Apple Configurator 二、Apple Configurator 注册组织, -----------这个组织可以是个人,或者其它组织导出-------再导入进来: 三、描述文件配置:“” 根据管控需求进行配置 “” 四、使用 Ap…...

Linux 管道(pipe)用法

在 Linux 中,管道(pipe)是一种特殊的机制,用于连接一个进程的标准输出到另一个进程的标准输入。通过使用管道,可以将一个命令的输出直接传递给另一个命令进行处理,实现了进程之间的通信和数据传输。 管道的…...

元素隐式具有 “any“ 类型,因为类型为 “string“ 的表达式不能用于索引类型

今天在写ts文件的过程中,我遍历了一个对象,然后取值的时候发现爆红,如下图👇 经过我一通排查(原因我对ts也不是很熟练),了解到大致意思是说key的值类型不是string类型,在javascript中是默认给你…...

34、springboot切换内嵌Web服务器(Tomcat服务器)与 生成SSL证书来把项目访路径从 HTTP 配置成 HTTPS

知识点1:springboot切换内嵌Web服务器(Tomcat服务器) 知识点2:生成SSL证书来把项目访路径从 HTTP 配置成 HTTPS ★ Spring Boot默认的Web服务器(Tomcat) ▲ 基于Servlet的应用(使用Spring MV…...

3种CSS实现背景图片全屏铺满自适应的方式

01 margin:0px; background: url(images/bg.png) no-repeat; background-size:100% 100%; background-attachment:fixed; url(images/beijing.png)——图片路径的位置; no-repeat—— 图片不重复; center 0px——center是距离页面左边的定位&#xf…...

M1 Pro 利用docker 搭建pytho2的开发环境,以vscode连接开发为例

使用 M1 Pro (不支持python2的安装)开发,需要使用 Python 2.7 的环境,在使用 pyenv 安装 Python 2 时遇到了各种奇怪的问题。最终,我决定使用 Docker 搭建开发环境,并使用 VS Code 连接到本地容器。以下是详…...

MySQL概述,架构原理

一.MySQL简介 MySQL是一个关系型数据库管理系统,由瑞典的MySQL AB公司开发,后被oracle公司收购,MySQL是当下最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的RDBMS(Relational Database Man…...

Three.js实现模型,模型材质可拖拽效果 DragControls

Three.js提供了一个拖拽的API DragControls 用于实现模型材质拖拽效果 DragControls:是一个用于在Three.js中实现拖拽控制的辅助类。它简化了在Three.js中实现拖拽物体的过程。 DragControls的构造函数接受三个参数: objects:一个包含需要…...

机器学习笔记之优化算法(二十)牛顿法与正则化

机器学习笔记之优化算法——再回首:牛顿法与正则化 引言回顾:经典牛顿法及其弊端牛顿法:算法步骤迭代过程中可能出现的问题正则化 Hessian Matrix \text{Hessian Matrix} Hessian Matrix与相应问题 引言 本节我们介绍经典牛顿法在训练神经网络过程中的迭…...

【Go 基础篇】深入探索:Go语言中的切片遍历与注意事项

嗨,Go语言学习者!在我们的编程旅程中,切片(Slice)是一个极其重要的工具。它可以帮助我们处理各种类型的数据,从而让我们的代码更加灵活和高效。本文将围绕Go语言中切片的遍历方法以及在遍历时需要注意的事项…...

一些经典的SQL语句

查sql中as的用法搜索到的一些经典的sql语句 convert(2008-11-20 18:03:50) In:等值连接,用来查找多表相同字段的记录 Not In:非等值连接,用来查找不存在的记录 Inner join:内连接,主要用来查找都符合条件的记录 Left join:左连接&#xff…...

〔018〕Stable Diffusion 之 批量替换人脸 篇

✨ 目录 🎈 下载插件🎈 插件基础使用🎈 基础使用效果🎈 批量处理图片🎈 多人脸部替换 🎈 下载插件 如果重绘图片的时候,你只想更换人物面部的话,可以参考这篇文章扩展地址&#xff…...

Unity字符串性能问题

前言 分享一些通过书籍和网络学到的知识 每次动态创建一个string,C#都会在堆内存分配一个内存用来分配字符串,因为C#没有对字符串的缓存机制,会导致每次连接、切割、组合的时候都会申请新的内存,并且抛弃原来的内存,等…...

深入浅出SSD:固态存储核心技术、原理与实战(文末赠书)

名字:阿玥的小东东 学习:Python、C/C 主页链接:阿玥的小东东的博客_CSDN博客-python&&c高级知识,过年必备,C/C知识讲解领域博主 目录 内容简介 作者简介 使用Python做一个计算器 本期赠书 近年来国家大力支持半导体行业&#xff0…...

关于layui+php,三级联动-编辑回显的问题。

注 忍不住吐槽一波。都什么年代了。现在都前后端分离,但是公司老项目非得用tplayui。。 代码如下 layui.use([form], function () {var form layui.form;//php代码渲染页面的时候,将一级分类id和二级分类id带过来,存到页面input框中&#x…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线, n r n_r nr​ 根接收天线的 MIMO 系…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...