2023.10.28 关于 synchronized 原理
目录
synchronized 特性
synchronized 优化机制
锁升级(锁膨胀)
其他优化机制
锁消除
锁粗化
synchronized 特性
- 开始时是乐观锁,如果锁冲突频繁,就转为悲观锁
- 开始是轻量级锁,如果锁被持有的时间较长,就转化成重量级锁
- 实现轻量级锁的时候大概率用到的自旋锁策略
- 是一个不公平锁
- 是一种可重入锁
- 不是读写锁
synchronized 优化机制
锁升级(锁膨胀)
- JVM 将 synchronized 分为以下四个状态,会根据情况,依次进行升级
- 无锁
- 偏向锁
- 轻量级锁
- 重量级锁
无锁状态
- 即代码还未执行到加锁的代码块中,该状态称为无锁状态
偏向锁状态
- 偏向锁的获取和释放操作开销非常低,几乎可以忽略不记,因为它不需要进行线程间的竞争和同步
- 当一个线程第一次尝试获取锁时,会将锁的标记设置为偏向锁,并将线程ID 记录在锁的元数据中
- 当同一个线程再次尝试获取锁时,无需竞争,直接获取到锁,不需要进行任何同步操作
- 如果在整个使用锁的过程中,都没有出现锁竞争,那在 synchronized 执行完之后,取消偏向锁即可
- 如果期间另一个线程尝试获取锁,偏向锁会自动撤销,升级为真正的加锁状态,从而另一个线程也就只能阻塞等待了
注意
- 偏向锁的使用是 JVM 自动进行的,开发人员无需显式地使用偏向锁
- JVM 会根据锁的竞争情况自动选择使用偏向锁、轻量级锁、重量级锁,以优化锁的性能和吞吐量
轻量级锁状态
- 当 synchronized 发生锁竞争的时候,就会从偏向锁,升级成轻量级锁
- 此时 synchronized 相当于通过 CAS 操作,以不断自旋的方式来进行加锁
- 如果别人很快就释放锁了,自旋是划算的,但是如果迟迟拿不到锁,一直自旋显然是不划算的,因为会长期占用的 CPU 资源,造成性能损失
重量级锁状态
- 当然 synchronized 自旋不是无休止的自旋,自旋到一定程度之后,就会再次升级成 重量级锁(挂起等待锁)
- 如果线程进行了重量级锁的加锁,并且发生锁竞争,此时线程就会被放到阻塞队列中,暂时不参与 CPU 调度了
- 然后直到锁被释放,这个线程才有机会被调度到,并且有机会获取到锁
- 一旦 线程被切换出 CPU,此时就会变得比较低效了
注意:
- 在 JVM 主流实现中,只有锁升级,没有锁降级
其他优化机制
锁消除
- 编译器智能的判定,看当前的代码是否真的要加锁
- 如果这个场景不需要加锁,程序员也加了,就自动把锁给干掉
实例理解
- StringBuffer 中的关键方法都带有 synchronized
- 如果在单线程中使用 StringBuffer,synchronized 加了也白加,此时编译器就会直接把这些加锁操作消除掉了
锁粗化
锁的粒度
- synchronized 包含的代码越多,粒度就越粗
- 包含的代码越少,粒度就越细
通常理解
- 一般情况下,认为锁的粒度细一点是比较好的
- 加锁部分的代码,是不能并发执行的
- 锁的粒度越细能并发的代码就越多,反之越少
- 但有些情况下,锁的粒度粗一些反而更好
- 如上图,这里的间隙非常小,就算并发了,也没啥太大效果
- 然而每次加锁都是带有开销的
- 此时并发节省的时间,反而不如加锁的开销大
- 所以我们不如将其转变为直接加一把大锁
- 上述过程就相当于锁粗化
相关文章:
2023.10.28 关于 synchronized 原理
目录 synchronized 特性 synchronized 优化机制 锁升级(锁膨胀) 其他优化机制 锁消除 锁粗化 synchronized 特性 开始时是乐观锁,如果锁冲突频繁,就转为悲观锁开始是轻量级锁,如果锁被持有的时间较长,…...
力扣 27. 移除元素
目录 1.解题思路2.代码实现 1.解题思路 利用双指针思路,当让一个指针先走,指针指向的位置不等于val时,将此时该指针的值给另一个指针并且两个指针都加一,如果等于val,则让该指针加一继续走.最后另一个指针的下标就为排好的数组的…...
redis爆满导致数据丢失
记一则redis爆满导致数据丢失的一场事故 某功能上线后,发现出现问题,最后定位到了 redis. 由于存储的数据过多,导致阿里云4G大小的 redis 爆满,触发了回收策略。 于是临时扩容,运维同学当时未找到阿里云配置。 后面我用工具连接了…...
Android14 WMS启动流程
一 概述 本文Android14源代码可参考:Search 在 Android 系统中,从设计的角度来看,窗口管理系统是基于 C/S 模式的。整个窗口系统分为服务端和客户端两大部分,客户端负责请求创建窗口和使用窗口,服务端完成窗口的维护…...
磁盘管理(初始化,引导块,坏块管理,固态硬盘)
目录 1.磁盘初始化2.引导块3.坏块的管理1.坏块检查2.坏块链表3.扇区备用 4.固态硬盘(SSD)1.原理2.组成3.读写性能特性4.与机械硬盘相比5.磨损均衡技术 1.磁盘初始化 ①进行低级格式化(物理格式化),将磁盘的各个磁道划分…...
mysql冷拷贝大表
1、简述: mysql数据迁移有多种方式,最常见的就是先把数据库导出,然后导入新的数据库。拷贝数据目录data是另外一种方式。 尤其是当数据库启动不了,或者大型数据库迁移的时候,可以考虑这个方式。 2、场景:…...
苍穹外卖-01
苍穹外卖-01 课程内容 软件开发整体介绍苍穹外卖项目介绍开发环境搭建导入接口文档Swagger 项目整体效果展示: 管理端-外卖商家使用 用户端-点餐用户使用 当我们完成该项目的学习,可以培养以下能力: 1. 软件开发整体介绍 作为一名…...
GAMP源码阅读(中)伪距单点定位 SPP
原始 Markdown文档、Visio流程图、XMind思维导图见:https://github.com/LiZhengXiao99/Navigation-Learning 文章目录 一、SPP 解算1、spp():单点定位主入口函数2、estpos()3、estpose_()4、valsol():GDOP和卡方检验结果有效性 二、卫星位置钟…...
Epinoia-有状态网络的意图验证模块,略读
Epinoia relies on a unified model for NFs by leveraging the causal precedence relationshipsthat exist between NF packet I/Os and states. 这句话的意思是:“Epinoia依靠一种统一的网络功能(NF)模型,通过利用存在于 NF 包…...
14.力扣c++刷题-->有效括号
题目:给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合…...
scrapy-redis分布式爬虫(分布式爬虫简述+分布式爬虫实战)
一、分布式爬虫简述 (一)分布式爬虫优势 1.充分利用多台机器的带宽速度 2.充分利用多台机器的ip地址 (二)Redis数据库 1.Redis是一个高性能的nosql数据库 2.Redis的所有操作都是原子性的 3.Redis的数据类型都是基于基本数据…...
单目深度估计之图像重构原理解析
一、参考资料 浅析自监督深度估计中的光度损失(Photometric Loss) 二、图像重构原理 设输入位姿估计网络的3帧连续单目序列为 < I t − 1 , I t , I t 1 > <I_{t-1},I_{t},I_{t1}> <It−1,It,It1>,其中 t t t 为时间索引,…...
【爬虫】charles手机抓包环境设置(设置系统证书)
1.说明 想要对手机抓包,最关键的是需要设置好根证书,用户证书在安卓7.0之后就不受信任了,想要对手机app抓包,就需要把用户证书设置为系统证书(根证书) 注意,想要设置为根证书,你的…...
【flink sql table api】时间属性的指定与使用注意事项
文章目录 一. 时间属性介绍二. Table api指定时间属性三. 处理时间的指定1. 在创建表的 DDL 中定义2. 在 DataStream 到 Table 转换时定义3. 使用 TableSource 定义 四. 事件时间的指定1. 在 DDL 中定义2. 在 DataStream 到 Table 转换时定义3. 使用 TableSource 定义 五. 小结…...
评价模型:CRITIC客观赋权法
目录 1.算法原理介绍2.算法步骤2.1 数据标准化2.2 计算信息承载量2.3 计算权重和得分 3.案例分析 1.算法原理介绍 CRITIC方法是一种客观权重赋权法,其基本思路是确定指标的客观权数以两个基本概念为基础。一是对比强度,它表示同一指标各个评价方案取值差…...
两个Tomcat插件配置不同端口,session冲突,同时登录被挤下线问题的解决
如果是配置了两个Tomcat的插件,在同一ip有两个需要同时登录的项目,可以在其中一个web项目的web.xml文件里添加session命名的配置,如下: <!--配置不同的session,避免管理端和手机端两个同时登录被挤下线--><se…...
Mybatis中执行Sql的执行过程
MyBatis中执行SQL的过程可以分为以下几个步骤: 解析配置文件:在运行时,MyBatis会加载并解析配置文件(通常为mybatis-config.xml),获取数据库连接信息、映射文件等。 创建SqlSessionFactory:MyB…...
IEEE Standard for SystemVerilog—Chapter 25.7 Tasks and functions in interfaces
子例程(任务和函数)可以在接口中定义,也可以在连接的一个或多个模块中定义。这允许更抽象的建模级别。例如,“读”和“写”可以定义为任务,而不需要引用任何连线,主模块只能调用这些任务。在modport中&…...
一台服务器最大能支持多少条 TCP 连接
文章目录 1. 一台服务器最大能打开的文件数1.1 限制参数1.2 调整服务器能打开的最大文件数示例 2. 一台服务器最大能支持多少连接3. 一台客户端机器最多能发起多少条连接4. 其他5. 相关实际问题5.1 "too many open files" 报错是怎么回事,该如何解决5.2 一…...
Qt重定向QDebug,Qt/C++开源作品39-日志输出增强版V2022
Qt重定向QDebug,自定义一个简易的日志管理类 Chapter1 Qt重定向QDebug,自定义一个简易的日志管理类0.前言1.最简单的操作运行结果2.实现一个简易的日志管理类 Chapter2 Qt::Qt Log日志模块Qt Log日志模块官方解释官方Demo思路 Chapter3 QT日志模块的个性…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

