<JavaEE> 锁进阶 -- synchronized 的锁优化

目录

一、如何形容 synchronized 锁

二、锁升级

2.1 偏向锁

2.2 轻量级锁

2.3 重量级锁

三、锁消除

四、锁粗化


一、如何形容 synchronized 锁

synchronized 锁是一个内部优化非常好的锁,大部分情况下这个锁都是适用的。
在初始阶段 synchronized 是一个乐观锁、轻量级锁、自旋锁,随着锁冲突变得更激烈,synchronized 会转换为悲观锁、重量级锁、挂起等待锁。

与此同时,synchronized 还是一个可重入锁、非公平锁、非读写锁。


二、锁升级

synchronized 的加锁过程
无锁偏向锁轻量级锁重量级锁

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

JVM 将 synchronized 锁分为 以上四个阶段,会根据实际情况,对锁进行升级。应该注意的是,目前所只能升级,不能降级。

2.1 偏向锁

阶段描述:
当锁第一次被一个线程获取时,优先进入偏向锁状态。
偏向锁并非真的“加锁”,而是在对象头中做一个“偏向锁标记”,记录该锁属于哪个线程。
如果后续没有其他线程竞争该锁,那么该锁不会有后续升级操作,减少了加锁带来的系统开销。
如果后续有其他线程竞争该锁,那么锁会真正的加锁,升级为轻量级锁。由于之前已经记录了该锁属于哪个线程,所以此时锁也是被记录的线程获取的。
这种升级操作实际上属于延迟加锁,不必要不加锁,减少了加锁的系统开销,提高了运行效率。

2.2 轻量级锁

阶段描述:
随着锁竞争的开始,锁将进入轻量级锁的状态,在初始状态是通过自旋锁实现的。
自旋锁是循环不断地让线程尝试获取锁。优点在于当锁被释放,其他线程可以第一时间获取到锁。
而自旋锁的缺点也在于会一直占用CPU资源。synchronized 对此也进行了优化,当自旋达到一定的时间或次数时,就不再自旋了,将转换为挂起等待。
同时,synchronized 内部也会统计当前锁对象有多少线程在竞争,如果锁竞争更加激烈,synchronized 就会从轻量级锁升级为重量级锁。

2.3 重量级锁

阶段描述:
重量级锁是指使用内核提供的 mutex 锁。
mutex 锁执行加锁操作时,会先进入内核态,在内核态判定当前锁是否已经被占用。
如果该锁没有被占用,则加锁成功,并切换回用户态。
如果该锁已经被占用,则加锁失败,线程阻塞等待,直到下一次唤醒。

三、锁消除

什么是锁消除?
锁消除是 synchronized 锁的一种较保守的优化策略,通过编译器和JVM判断锁是否可以消除。
这里的锁消除只会处理一些直接可以判断,完全不涉及线程安全问题的锁,比如在单线程环境下使用 StringBuffer 类中的方法。

四、锁粗化

什么是锁粗化?
这里有一个锁的粒度的概念,可以这么认为:在锁对象代码块中的代码越少则认为锁的粒度越细,反之则是越粗。
实际开发中,使用细粒度的锁,往往是为了锁可以被其他线程及时获取。但有时,可能很长一段时间都没用其他线程来竞争这个锁。
因此,如果一段逻辑中出现多次加锁解锁,根据编译器和JVM的判断会自动对锁进行粗化。
锁粗化是指将多个细粒度的锁合并为一个粗粒度的锁,可以在特定场景下提高程序的执行效率,减小系统开销。

阅读指针 -> 《CAS编程及相关类》

链接生成中..........

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

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

相关文章

分布式搜索引擎02

分布式搜索引擎02 在昨天的学习中,我们已经导入了大量数据到elasticsearch中,实现了elasticsearch的数据存储功能。但elasticsearch最擅长的还是搜索和数据分析。 所以今天,我们研究下elasticsearch的数据搜索功能。我们会分别使用DSL和Res…

react面试总结2

redux中sages和thunk中间件的区别,优缺点 Redux 中的 redux-saga 和 redux-thunk 都是中间件,用于处理异步操作,但它们有一些区别。 Redux Thunk: 简单易用:redux-thunk 是比较简单直观的中间件,它允许 …

手撕分布式缓存---HTTP Server搭建

经过了前两个章节的学习,分布式缓存的存储与新增我们已经实现了,并且对其做了高可用处理。本章节我们剥离和缓存强相关的逻辑,开始搭建一个HTTP服务器,毕竟缓存数据库搭建完之后别人没法访问也是没有用处的。这一章节我们重点学习…

ElasticSearch应用场景以及技术选型[ES系列] - 第496篇

历史文章(文章累计490) 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 M…

PDF控件Spire.PDF for .NET【转换】演示:将 PDF 转换为 Excel

PDF是一种通用的文件格式,但它很难编辑。如果您想修改和计算PDF数据,将PDF转换为Excel将是一个理想的解决方案。在本文中,您将了解如何使用Spire.PDF for .NET在 C# 和 VB.NET 中将 PDF 转换为 Excel。 Spire.Doc 是一款专门对 Word 文档进行…

【华为数据之道学习笔记】3-10元数据管理架构及策略

元数据管理架构包括产生元数据、采集元数据、注册元数据和运 维元数据。 产生元数据: 制定元数据管理相关流程与规范的落地方案,在IT产品开发过程中实现业务元数据与技术元数据的连接。 采集元数据: 通过统一的元模型从各类IT系统中自动采集元…

多线程(初阶九:线程池)

目录 一、线程池的由来 二、线程池的简单介绍 1、ThreadPoolExecutor类 (1)核心线程数和最大线程数: (2)保持存活时间和存活时间的单位 (3)放任务的队列 (4)线程工…

Axure的安装以及简单使用

目录 Axure简介 是什么 有什么用 Axure的优缺点 优点: 缺点: 安装 汉化 Axure的使用 工具栏 页面 ​编辑 添加子页面 ​编辑 Axure简介 是什么 Axure是一款著名的原型设计工具。它允许用户创建交互式线框图、流程图、原型和其他设计文档&…

「Verilog学习笔记」脉冲同步电路

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网 timescale 1ns/1nsmodule pulse_detect(input clk_fast , input clk_slow , input rst_n ,input data_in ,output dataout );reg data_level, dat…

第十一章 React 封装自定义组件

一、专栏介绍 🌍🌍 欢迎加入本专栏!本专栏将引领您快速上手React,让我们一起放弃放弃的念头,开始学习之旅吧!我们将从搭建React项目开始,逐步深入讲解最核心的hooks,以及React路由、…

【NLP】RAG 应用中的调优策略

​ 检索增强生成应用程序的调优策略 没有一种放之四海而皆准的算法能够最好地解决所有问题。 本文通过数据科学家的视角审视检索增强生成(RAG)管道。它讨论了您可以尝试提高 RAG 管道性能的潜在“超参数”。与深度学习中的实验类似,例如&am…

关于jinja2高版本api变化导致notebook导出html失败的问题

最新jinja2版本已经到了3.1.2,但是nbconvert引用的应该是老版本,具体代码报错如下 Type "help", "copyright", "credits" or "license" for more information. >>> import nbconvert Traceback (most…

spark从表中采样(随机选取)一定数量的行

在Spark SQL中,你可以使用TABLESAMPLE来按行数对表进行采样。以下是使用TABLESAMPLE的示例: SELECT * FROM table_name TABLESAMPLE (1000 ROWS);在这个示例中,table_name是你要查询的表名。TABLESAMPLE子句后面的(1000 ROWS)表示采样的行数…

axios 基础的 一次封装 二次封装

一、平常axios的请求发送方式 修改起来麻烦的一批 代码一大串 二、axios的一次封装 我们会在src/utils创建一个request.js的文件来存放我们的基地址与拦截器 /* 封装axios用于发送请求 */ import axios from axios/* (1)request 相当于 Axios 的实例对象 (2)为什么要有reque…

VSCode使用Remote-SSH连接服务器时报错:无法与“***”建立连接: XHR failed.

关于VSCode的报错问题:无法与“***”建立连接: XHR failed 问题描述问题理解解决方法手动在本地下载安装包,然后手动传到服务器端 问题描述 是的,我又踩坑了,而且这个弄了好久,也重新装了VSCode软件,好像结…

2024黑龙江省职业院校技能大赛暨国赛选拔赛“GZ031应用软件系统开发”赛项赛题题库

2024黑龙江省职业院校技能大赛暨国赛选拔赛 “GZ031应用软件系统开发”赛项赛题题库 2024黑龙江省职业院校技能大赛暨国赛选拔赛 应用软件系统开发赛项(高职组) 赛题第1套 目录 竞赛说明 模块一:系统需求分析 任务1:制造执行…

Kotlin之for循环的具体使用说明

我们用java进行Android开发过程中,经常会用到for循环,在Kotlin中也会经常用到,但是在最近使用Kotlin中我发现,在java中使用for循环不会有什么问题,但是在Kotlin中会出现问题,就是循环出出来的结果不一样&am…

前端框架(Front-end Framework)和库(Library)的区别

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

阿里云国际版CDN加速,如何判断网站IP已加速?

将源站接入阿里云CDN服务后,您可以通过IP检测功能,检测客户端请求实际访问的IP是否为CDN加速节点IP,判断加速是否生效。 应用场景 IP检测的应用场景如下: 场景一:成功配置CDN后,您可以检测客户端请求实际…

Android popupwindow在低版本手机上无法显示

所以我开始看各个参数,注意到了在我自定义popupwindow的builder下的:👇👇 .showAsDropDown(mLinMain, 0, 0);就是这个,这时候我想到了屏幕的原点坐标是(0, 0),所设置的p…