详解Java Synchronized锁升级原理

news2024/7/5 0:05:31

✅作者简介:热爱Java后端开发的一名学习者,大家可以跟我一起讨论各种问题喔。
🍎个人主页:Hhzzy99
🍊个人信条:坚持就是胜利!
💞当前专栏:JAVA多线程
🥭本文内容:深入理解Synchronized锁升级原理。


文章目录

  • 引言
    • 偏向锁
    • 轻量级锁
    • 重量级锁
    • 锁的升级过程
  • 结语


引言

在Java中,synchronized是一个非常重要的关键字,它为开发者提供了一种便捷的方式来控制并发。但要充分利用它的威力,我们需要理解其内部的工作原理。本篇博客将深入探讨synchronized关键字背后的机制,特别是锁的升级过程。

锁升级原理

偏向锁

在JDK1.6之前,Synchronized底层是调用了操作系统的Mutex Lock,所以使用Synchronized会从用户态向内核态转换,会有性能的损耗,在JDK 1.6引入了偏向锁,这是一种针对单线程的优化。它假设没有线程会竞争锁,因此直接将锁偏向于首次请求它的线程。如果在后续的执行过程中,该锁没有被其他线程请求,则持有偏向锁的线程无需再进行同步操作,这就避免了无竞争情况下的同步原语的开销。

轻量级锁

轻量级锁是针对多线程轮流进入同步块的场景进行优化的。当一个线程进入同步块时,如果同步对象未被锁定,JVM会在当前线程的栈帧中创建用于存储锁记录的空间,并将对象头的信息复制到锁记录中,再尝试用CAS将对象头的信息替换为指向锁记录的指针。如果成功,当前线程则获取到了锁。如果失败,表示其他线程竞争该锁,那么当前线程便尝试使用自旋来获取锁。

重量级锁

重量级锁是当有多个线程同时竞争同一把锁时的情况。当线程无法获得轻量级锁,且自旋等待的策略失败后,锁会膨胀为重量级锁。此时,无法获取锁的线程会进入操作系统的等待队列,陷入阻塞状态。这种状态下的线程调度需要切换到内核态进行操作,开销比前两种锁更大。

锁的升级过程

Java的锁升级过程是由偏向锁向轻量级锁,再向重量级锁进行升级。

从偏向锁升级到轻量级锁的触发条件是:当一个线程持有偏向锁,而另一个线程试图锁定同一对象时,偏向锁就会被撤销,锁会升级为轻量级锁 (只要有两个线程同时竞争,就会升级)

从轻量级锁升级到重量级锁的触发条件是:在持有轻量级锁的线程还未释放锁的情况下,有其他线程试图获取该轻量级锁,并且自旋等待已经失败 (竞争激烈,自选次数超过阈值)

这种锁的升级设计考虑了减少锁的竞争对系统性能的影响。在无锁竞争和轻度竞争的情况下,通过偏向锁和轻量级锁减少不必要的重量级锁导致的线程上下文切换。在激烈的锁竞争情况下,使用重量级锁,让线程进入阻塞状态,从而让CPU有更多的时间处理其他任务。

结语

理解synchronized的内部原理和锁的升级过程,对于编写高效的并发代码是非常有帮助的。希望本篇博客能帮助你理解和掌握这个重要概念。在并发编程的道路上,我期待你能走得更远,成就更大。

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

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

相关文章

蓝桥杯专题-试题版含答案-【猴子吃桃问题】【小光棍数】【九九乘法表】【谁是最好的Coder】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

(Linux) 套接字socket基础

文章目录 前言基本原理 Codeserverclient 核心函数socketbindlistenacceptrecvsendconnectclose 多线程改进END 前言 本文将以纯C语言描述,编译器gcc。 C/C没有标准的网络库,因为都需要用到各个平台的接口才行。 本文讲解Linux下最基础的socket编程&a…

uniapp 常用提示弹框整理

一. 加载提示弹框 在执行数据查询、页面数据渲染等过程中弹出提示。以页面渲染为例: //前端数据请求时,显示加载提示弹框 uni.showLoading({title: 加载中... }); // 数据从后端接口返回后,提示弹框关闭 uni.hideLoading();效果如下&#x…

Sui Builder House京都站|创意大赛获奖名单公布

Sui Builder House京都站于6月30日(周五)圆满结束,这是一次Sui生态系统项目演示和展示各自产品的良好机会。构建者们向大家展示了游戏、NFT、DeFi和基础设施赛道的项目,同时现场演讲还介绍了Sui的最新进展以及有关AI和用户体验设计…

React环境安装配置

React环境安装配置 一、前提二、React安装 一、前提 安装本地React环境需要Node.js,如果具有Node环境跳过即可。如果没有安装则可参考该篇文章安装Node环境,点击查看 二、React安装 全局安装React 首先打开命令行,建议以管理员身份输入命…

20230704测试STC32G实验箱9.6(STC32G12K128)开发板的虚拟串口(C语言深入了解)

20230704测试STC32G实验箱9.6(STC32G12K128)开发板的虚拟串口(C语言深入了解) 06第五集:C语言运算符和进制数入门上.mp4 07第五集:C语言运算符和进制数入门下.mp4 2023/7/4 19:00 下次 在【冲哥】录视频的时…

024、数据库管理之数据同步工具TiCDC

TiCDC TiCDCTiCDC介绍架构与原理适用场景对已有TiDB进行扩容部署TiCDC管理工具TiCDC同步任务查询所有TiCDC同步任务查询TiCDC指定的同步任务管理TiCDC同步任务动态更新任务监控TiCDC 实验数据同步完整实操缩容当前TiCDC节点 TiCDC TiCDC介绍 TiCDC 是一款通过拉取 TiKV 变更日…

leetcode 42-接雨水

解法一:双指针(暴力按列计算) 首先,如果按照列来计算的话,宽度一定是1了,我们再把每一列的雨水的高度求出来就可以了。 可以看出每一列雨水的高度,取决于该列左侧最高的柱子和右侧最高的柱子中…

VMware虚拟机的基本操作:快照和克隆

VMware虚拟机的基本操作 一、虚拟机快照二、克隆 一、虚拟机快照 “快照”是虚拟机磁盘文件(VMDK)在某个点及时的副本。系统崩溃或系统异常,你可以通过使用恢复到快照来保持磁盘文件系统和系统存储。当升级应用和服务器及给它们打补丁的时候…

一桩关于Json序列化引发的惨案(Go系统)

文章目录 前言突然崩了排查问题关于go的json库什么是反射 解决大结构体序列化的性能问题干掉大结构体减少反射使用一些好用的第三方序列化包 自定义序列化 写在最后 前言 一个风和日丽的下午,线上系统突然开始报警(系统温馨提示,您的服务接口…

部署Git服务器

哈喽,大家好,本次为大家演示如何部署git服务器. 首先要准备gitea和phpstudy_pro phpstudy一路nest即可,可以帮你安装mysql和阿帕奇。 登录127.0.0.1:3000注册gitea即可。 如何在上传公钥的时候出现500的错误,加入这句便可解决…

SpringBoot+Vue+Element-ui实现文件下载

目录 1.后端代码部分 2.前端代码部分 3.效果展示 1.后端代码部分 GetMapping("downloadFile")public void downloadFile(RequestParam("filename") String filename,HttpServletResponse response) throws Exception {// 告知浏览器这是一个字节流&…

WebSocket connection to “wss://xxx/xxx“ failed

用了https后,需要用nginx作websocket地址的转发才能使用wss,别直接用端口访问 location /ws/ {proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upgrade"; proxy_pass http://localhost:10001/…

JVM源码剖析之SymbolTable和StringTable

很多读者在观看JVM相关的书籍时会看到SymbolTable和StringTable,书中的三言二语介绍的不是很清楚,并且读者的水平有限,导致无法理解SymbolTable和StringTable。所以特意写此篇图文并茂的文章来彻底理解SymbolTable和StringTable这两张表。 版…

Java面试Day16

1.Dubbo 是什么?是否了解过它的架构设计? Dubbo官网:Apache Dubbo Dubbo是一个高性能、轻量级的开源Java RPC框架,它提供了完整的RPC协议栈,包括服务发布、服务引用、负载均衡、容错、服务治理和服务监控等功能&#…

构造函数使用初始化列表+模板

构造函数使用初始化列表模板 注意对应关系&#xff1a; Stack(int size) ;template<class DataType> inline Stack<DataType>::Stack(int size) : stacksize(size), top(0) {item new DataType[stacksize];if (item ! nullptr) cout << "成功初始化栈&…

再见!Fastjson!

你为何仍用Fastjson&#xff1f; 原因可以说出5678种&#xff0c;总而言之言而总之&#xff0c;你不&#xff08;敢&#xff09;切换的原因或许只有一个&#xff1a;Fastjson的静态方法调用用着省心&#xff1b;最重要的是&#xff0c;对其它JSON库&#xff08;如Jackson/Gson…

【生活分享】《哈姆雷特》· 苏州站 - 一次有趣的音乐剧体验

平时博客里大部分都是写技术相关的文章&#xff0c;感觉内容还是比较单一的&#xff0c;也想分享一下最近的一些有趣的生活~ 6月30号的时候&#xff0c;便订好了徐俊导演编排的7月2号场《哈姆雷特》音乐剧。而实际上&#xff0c;苏州场7月1号就上映了&#xff0c;感觉那天太晚……

C++图形开发(6):落下后能弹起的小球

文章目录 1.重复下落的小球2.落下后能弹起的小球3.能上下反弹的小球4.符合重力的能上下反弹的小球 今天我们来尝试实现一个落地后可以弹起的小球 1.重复下落的小球 首先&#xff0c;我们要来实现一个小球的重复下落 我们知道&#xff0c;在前面的代码中&#xff08;详见C图形…

云his源码:医疗卫生信息系统

伴随着以5G、云计算、大数据、人工智能和物联网等新兴技术的发展&#xff0c;医疗行业也呈现了数字化的发展趋势。如何让医疗领域中的服务提供方、需求方、支付方以及供应链等参与方实现业务协同及数据协同&#xff0c;是目前医疗行业所需的能力。 HIS系统&#xff0c;即“医疗…