Synchronized同步锁的优化方法 待完工

Synchronized 和后来出的这个lock锁的区别

在并发编程中,多个线程访问同一个共享资源时,我们必须考虑如何维护数据的原子性。在
JDK1.5 之前,Java 是依靠 Synchronized 关键字实现锁功能来做到这点的。Synchronized 是 JVM 实现的一种内置锁,锁的获取和释放是由 JVM 隐式实现。

到了 JDK1.5 版本,并发包中新增了 Lock 接口来实现锁功能,它提供了与 Synchronized
关键字类似的同步功能,只是在使用时需要显示获取和释放锁

Lock 同步锁是基于 Java 实现的,而 Synchronized 是基于底层操作系统的 Mutex Lock
实现的,每次获取和释放锁操作都会带来用户态和内核态的切换,从而增加系统性能开销

因此,在锁竞争激烈的情况下,Synchronized 同步锁在性能上就表现得非常糟糕,它也常
被大家称为重量级锁。

1.6以后呢对这个Synchronized 锁进行了升级,引入了锁升级,某些程度上来说呢。再某些业务场景已经超过了lock。

这里再次生明Synchronized 是关键字,而lock是通过是西安这个lock接口来实现这个所功能的。

Synchronized 底层原理 ,也就是他的同步原理

通常 Synchronized 实现同步锁的方式有两种,一种是修饰方法,一种是修饰方法块。以
下就是通过 Synchronized 实现的两种同步方法加锁的方式:

 javac -encoding UTF-8 SyncTest.java // 先运行编译 class 文件命令

javap -v SyncTest.class // 再通过 javap 打印出字节文件

通过以上命令去反编译出这个文件的字节码文件可以看到

你会发现:Synchronized 在修饰同步代码块时,是由 monitorenter和 monitorexit 指令来实现同步的。进入 monitorenter 指令后,线程将持有 Monitor 对象,退出 monitorenter 指令后,线程将释放该 Monitor 对象。注意修饰的代码块

而同步方法的字节码中,你会发现:当 Synchronized 修饰同步方法时,并没有发
monitorenter 和 monitorexit 指令,而是出现了一个 ACC_SYNCHRONIZED 标志。

这是因为 JVM 使用了 ACC_SYNCHRONIZED 访问标志来区分一个方法是否是同步方法

当方法调用时,调用指令将会检查该方法是否被设置 ACC_SYNCHRONIZED 访问标志。
如果设置了该标志,执行线程将先持有 Monitor 对象,然后再执行方法。在该方法运行期
间,其它线程将无法获取到该 Mointor 对象,当方法执行完成后,再释放该 Monitor 对
象。

 再来看看 Synchronized 修饰方法是怎么实现锁原理的。

JVM 中的同步是基于进入和退出管程(Monitor)对象实现的。每个对象实例都会有一个
Monitor,Monitor 可以和对象一起创建、销毁。

当多个线程同时访问一段同步代码时,多个线程会先被存放在 EntryList 集合中,处于
block 状态的线程,都会被加入到该列表。接下来当线程获取到对象的 Monitor 时,
Monitor 是依靠底层操作系统的 Mutex Lock 来实现互斥的,线程申请 Mutex 成功,则持
有该 Mutex,其它线程将无法获取到该 Mutex。

注意阅读下图

 如果线程调用 wait() 方法,就会释放当前持有的 Mutex,并且该线程会进入 WaitSet 集合
中,等待下一次被唤醒。如果当前线程顺利执行完方法,也将释放 Mutex。

这里插播一下 wait和sleep都释放锁码?好像写代码的时候遇到过

 因 Monitor 是依赖于底层的操作系统实现,存在用户态与内核态之间的切换,所以增加了性能开销。

锁升级优化

为了提升性能,JDK1.6 引入了偏向锁、轻量级锁、重量级锁概念,来减少锁竞争带来的上
下文切换,而正是新增的 Java 对象头实现了锁升级功能。
当 Java 对象被 Synchronized 关键字修饰成为同步锁后,围绕这个锁的一系列升级操作都
将和 Java 对象头有关。

Java 对象头

在 JDK1.6 JVM 中,对象实例在堆内存中被分为了三个部分:对象头、实例数据和对齐填
充。其中 Java 对象头由 Mark Word、指向类的指针以及数组长度三部分组成

Mark Word 记录了对象和锁有关的信息。Mark Word 在 64 位 JVM 中的长度是 64bit

 锁升级功能主要依赖于 Mark Word 中的锁标志位和释放偏向锁标志位,Synchronized 同
步锁就是从偏向锁开始的,随着竞争越来越激烈,偏向锁升级到轻量级锁,最终升级到重量
级锁。

1. 偏向锁

偏向锁主要用来优化同一线程多次申请同一个锁的竞争。在某些情况下,大部分时间是同一
个线程竞争锁资源,例如,在创建一个线程并在线程中执行循环监听的场景下,或单线程操
作一个线程安全集合时,同一线程每次都需要获取和释放锁,每次操作都会发生用户态与内
核态的切换。

 再自己的同步代码块里加锁,同步代码块有全局变量,我们枷锁,让它不被别的线程修改

偏向锁的作用就是,当一个线程再次访问这个同步代码或方法时,该线程只需去对象头的
Mark Word 中去判断一下是否有偏向锁指向它的 ID,无需再进入 Monitor 去竞争对象
了。

当对象被当做同步锁并有一个线程抢到了锁时,锁标志位还是 01,“是否偏向锁”标
志位设置为 1,并且记录抢到锁的线程 ID,表示进入偏向锁状态。

一旦出现其它线程竞争锁资源时,偏向锁就会被撤销。偏向锁的撤销需要等待全局安全点,
暂停持有该锁的线程,同时检查该线程是否还在执行该方法,如果是,则升级锁,反之则被
其它线程抢占。

下图中红线流程部分为偏向锁获取和撤销流程:

 

 

 

偏向锁这个设计到一个调优 高并发

在高并发场景下,当大量线程同时竞争同一个锁资源时,偏向锁就会被撤销,发生
stop the world 后, 开启偏向锁无疑会带来更大的性能开销,这时我们可以通过添加 JVM
参数关闭偏向锁来调优系统性能

 

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

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

相关文章

element表格+表单+表单验证结合运用

目录​​​​​​​ 一、结果展示 二、实现代码 一、结果展示 1、图片 2、描述 table中放form表单,放输入框或下拉框或多选框等; 点击添加按钮,首先验证表单,如果存在没填的就验证提醒,都填了就向下添加一行表单表…

react中hooks分享

一. HOOKS是什么 在计算机程序设计中,钩子一词涵盖了一系列技术,这些技术用来通过拦截函数调用、消息或在软件组件之间传递的事件来改变或增加操作系统、应用程序或其他软件组件的行为。处理这些被截获的函数调用、事件或消息的代码称为“hook”。 在r…

Spring Boot数据访问基础知识与JDBC简单实现

目录 Spring Boot数据访问基础知识 Spring Data ORM JDBC JPA JDBC简单实现 步骤1:新建Maven项目,添加依赖 步骤2:配置数据源—让程序可以访问到 步骤3:配置数据源—让IDEA可以访问到 步骤4:添加数据库和表 …

人类与机器的分类不同

分类能力也是智能的重要标识之一。通过分类,我们可以将事物或概念进行归类和组织,从而更好地理解和处理信息。分类在人类认知和智能发展中起到了重要的作用,它有助于我们对世界进行认知、记忆、推理和决策。在机器智能领域,分类同…

在WebStorm中通过live-server插件搭建Ajax运行环境

1.下载node.js 官网: https://nodejs.cn/download/ 2.配置Node.js的HTTPS 使用淘宝的镜像: npm config set registry https://registry.npm.taobao.org 也可以使用cnpm npm install -g cnpm --registryhttps://registry.npm.taobao.org 配置之后可以验证是否成…

Windows安装子系统Linux

Windows安装子系统(Linux ubuntu) 安装条件步骤1.安装WSL命令2.设置Linux用户名和密码3.写个简单的.c程序看看4.如何互传文件 安装条件 Windows 10版本2004及更高的版本才能安装。 步骤 1.安装WSL命令 我们可以使用WSL来安装子系统 Linux ubuntu(默认是这个)。 …

Docker网络模式详解

目录 Docker网络模式 一、Host模式 二、container模式 三、none模式 四、bridge模式 五、Overlay模式 Docker网络模式 安装Docker时会自动创建3个网络,可以使用docker network ls命令列出这些网络。 [rootdocker ~]# docker network ls 我们在使用docker run…

进程、线程、协程

目录 进程、线程、协程的概念 进程、线程、协程的上下文切换 使用协程的注意事项 协程与线程、进程的区别 进程、线程、协程的概念 进程: 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程…

【雕爷学编程】Arduino动手做(195)---HT16k33 矩阵 8*8点阵屏模块5

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…

HikariDataSource类的作用和使用

HikariDataSource是一个Java数据库连接池的实现,它属于HikariCP连接池库。连接池是一个用于管理数据库连接的工具,它可以帮助优化数据库连接的创建和销毁过程,提高数据库操作的性能和效率。 HikariDataSource类的作用是创建和管理数据库连接…

企业服务器器中了360后缀勒索病毒怎么解决,勒索病毒解密数据恢复

随着网络威胁的增加,企业服务器成为黑客攻击的目标之一。近期,上海某知名律师事务所的数据库遭到了360后缀的勒索病毒攻击,导致企业服务器内的数据库被360后缀勒索病毒加密。许多重要的数据被锁定无法正常读取,严重影响了企业的正…

运维作业—5

一.基于 CentOS 7 构建 LVS-DR 群集 1.配置LVS 2.第一台real server(192.168.100.139:80) 手工在RS端绑定VIP 手工在RS端抑制ARP响应 3.第二台real server(192.168.100.140:80) 安装arptables并启动 使用arptables实现抑制 测试…

通向架构师的道路之weblogic与apache的整合与调优

一、BEAWeblogic的历史 BEA WebLogic是用于开发、集成、部署和管理大型分布式Web应用、 网络应用和数据库应 用的Java应用服务器。将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用的 开发、集成、部署和管理之中。 BEA WebLogic Server拥有处理关键Web应…

webpack性能优化

文章目录 1. 性能优化-分包2. 动态导入3. 自定义分包4. Prefetch和Preload5. CDN加载配置6. CSS的提取7. terser压缩7.1 Terser在webpack中配置7.2 css压缩 8. Tree Shaking 消除未使用的代码8.1 usedExports 配置8.2 sideEffects配置8.3 CSS实现Tree Shaking 9. Scope Hoistin…

Qgis核密度分析

不建议使用Qgis进行核密度分析,建议使用arcgis,arcgis更简单。 arcgis核密度分析 Qgis核密度分析有两种: 法一:符号化,热图。 缺点:使用不方便,只适合看一下效果。 法二:工具栏搜索&#xff…

网络安全预警分类流程

网络安全预警指南 随着信息技术的广泛应用与快速发展,传统业务与信息系统的融合程度不断加深,网络安全对国家政治、经济、文化、公共服务活动的影响进一步增大。网络安全形势日趋复杂,安全威胁不断变化,利用网络漏洞、恶意程序从…

MySQL的索引使用的数据结构,事务知识

一、索引的数据结构🌸 索引的数据结构(非常重要) mysql的索引的数据结构,并非定式!!!取决于MySQL使用哪个存储引擎 数据库这块组织数据使用的数据结构是在硬盘上的。我们平时写的代码是存在内存…

【JAVA】数组

⭐ 作者:小胡_不糊涂 🌱 作者主页:小胡_不糊涂的个人主页 📀 收录专栏:浅谈Java 💖 持续更文,关注博主少走弯路,谢谢大家支持 💖 数组 1. 数组的基本概念1.1 为什么要使用…

SCT82A30DHKR_5.5V-100V Vin同步降压控制器

SCT82A30是一款100V电压模式控制同步降压控制器,具有线路前馈。40ns受控高压侧MOSFET的最小导通时间支持高转换比,实现从48V输入到低压轨的直接降压转换,降低了系统复杂性和解决方案成本。如果需要,在低至6V的输入电压下降期间&am…

策略模式(Strategy)

策略模式是一种行为设计模式,就是定义一系列算法,然后将每一个算法封装起来,并使它们可相互替换。本模式通过定义一组可相互替换的算法,实现将算法独立于使用它的用户而变化。 Strategy is a behavioral design pattern that def…