当前位置: 首页 > 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…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

腾讯云V3签名

想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...

Bean 作用域有哪些?如何答出技术深度?

导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答&#xff0c…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析,分为​​已启动​​和​​未启动​​两种场景: 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​:当其他组件(如Activity、Service)通过ContentR…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

字符串哈希+KMP

P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...