Java 虚拟机对Synchronized的优化

Java虚拟机对synchronized的优化 锁的状态总共有四种,无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁,但是锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级,关于重量级锁,前面我们已详细分析过,下面我们将介绍偏向锁和轻量级锁以及JVM的其他优化手段,这里并不打算深入到每个锁的实现和转换过程更多地是阐述Java虚拟机所提供的每个锁的核心优化思想,毕竟涉及到具体过程比较繁琐... 阅读详情

​Java虚拟机 Synchronized的优化 自旋锁,自适应的自旋锁,偏向锁,轻量级锁,锁膨胀,重量级锁

                                                                               2018年拍摄于日本京都金阁寺

微信公众号

 

王皓的GitHub:https://github.com/TenaciousDWang

 

      上一回说了Synchronized同步代码块的使用及简单原理,这一回说一下JDK1.5到JDK1.6对于Synchronized的一个重要改进,用来提高并发效率,这一回主要会介绍自旋锁,自适应的自旋锁,锁膨胀,轻量级锁,偏向锁,现在我们把传统的Synchronized定义为重量级锁。

 

    JVM的虚拟机开发团队为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁,以及锁的存储结构和升级过程。

 

    自旋锁,我们前面知道Synchronized是一种互斥锁,通过对一个资源加锁保证一个线程对其执行操作,其他线程没有获取到锁时将处于阻塞状态,将线程挂起与恢复线程,每个线程都需要记录程序计数器和CPU寄存器状态,存储和恢复每个线程的执行状态,都是是资源开销,也会造成效率下降。

 

    JVM虚拟机的开发团队发现有一些共享数据被锁定的时间其实很短,为了这么短的时间去挂起和恢复线程不太值得,所以假设有一个线程在使用共享资源,第二个线程需要访问时不需要挂起线程,也就是说不放弃CPU时间片执行时间,而是等待第一个持有锁的线程是否很快的释放锁,为了让线程等待且不放弃CPU执行时间,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环,这就是自旋锁。

 

    自旋等待并不能代替阻塞,首先至少两个线程都获取到CPU执行时间,首先对处理器数量是有要求的,自旋虽然避免了线程切换的开销,但是其仍然占用CPU执行时间,如果自旋时间短则效果会非常好,如果等待时间较长,那么就会长时间浪费处理器资源。

 

    在虚拟机中,自旋默认次数为10,我们可以通过设置JVM参数-XX:PreBlockSpin来更改,达到自旋次数后会按照传统方式挂起线程。

 

  自旋锁在Java 1.4.2时就引入了,默认为关闭,可以使用-XX:+UseSpinning参数来开启,Java 1.6时已经默认开启,并且引入了自适应的自旋锁,当一个线程通过自旋获取到锁后,JVM会认为其很可能再次成功,所以每次自旋获得锁时,自旋时间都会延长,相反如果一个线程很少通过自旋获取锁,则该线程以后则会被JVM忽略自旋,直接使其挂起,避免浪费资源。

 

    在说轻量锁与偏向锁,锁膨胀之前,我们需要先了解Java对象头的内存布局,这里参考了周志明《深入理解Java虚拟机》,在32位与64位的JVM虚拟机中对象头的大小分别为32bit与64bit,如果不是数组对象则分为两部分,数组对象多一个部分存储数组长度。

 

名称

内容说明

Mark Word

存储对象的hashCode或锁信息等。

Class Metadata Address

存储到对象类型数据的指针

Array length

数组的长度(如果当前对象是数组)

 

    Mark Word中所记录的锁标志位是实现轻量级锁与偏向锁的关键,接下来我们以32位JVM的Mark Word组成来看一下:32bit中有25bit用于存储对象HashCode,4bit用于存储对象分代年龄,2bit用于存储锁标志位,1bit固定为0,注意这些空间的大小不是固定的,会随着状态变化而发生改变,为了JVM的空间效率,在最小的空间内尽量存储更多的信息。

 

 

    在了解了Mark Word里存有锁标志位后,我们现在先了解一下锁的状态,在Java 1.6+里锁一共有四种状态,无锁状态,偏向锁状态,轻量级锁状态和重量级锁状态,它会随着竞争情况逐渐升级。锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁。

 

    首先我们来说一下偏向锁,偏向锁就是偏向第一个获取锁的线程,在无竞争状态下,同步与CAS操作都不做了,如果一直没有其他线程去获取锁,则一直偏向,偏心下去,永远不需要再进行同步。

 

    这里的CAS操作指compare and swap(比较与交换),是一种有名的无锁算法。无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。CAS算法涉及到三个操作数

 

  • 需要读写的内存值 V
  • 进行比较的值 A(预期值,写入B之前重新获取V)
  • 拟写入的新值 B

 

    CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。一般情况下是一个自旋操作,即不断的重试。

 

    当锁对象第一次被线程获取时,JVM会把该对象头中的锁标志位改为01,即可偏向(偏向锁)状态,同时使用CAS操作将线程ID写入Mark Work之中,如果CAS操作成功,则持有该锁的线程每次进入该同步块时,就可以不做任何同步操作。

 

    当有另一个线程去获取锁对象时,根据CAS算法规则会操作失败,即写入失败,此时会根据锁对象状态来判定,如果锁对象处于未锁定状态则撤销偏向锁标记恢复为未锁定状态01,如果锁定则将锁标记设置为00,升级为轻量级锁状态。

 

    轻量级锁加锁,线程在执行同步块之前,JVM会先在当前线程的栈桢中创建用于存储锁记录的空间,锁记录(Lock Record),并将对象头中的Mark Word复制到锁记录中,copy的记录官方称为Displaced Mark Word。然后线程尝试使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁。

 

                                                                  图片引用自周志明《进入理解JVM虚拟机》

 

 

    如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁,这个就是轻量级锁,实际上为一个线程占用,另一个线程处于自旋状态,节省互斥开销。

 

    超过两个线程竞争时轻量锁不再有效,这时膨胀为重量级锁,锁标记会被JVM设置为10,进入重量锁状态,即互斥状态,其他竞争线程不再自旋而进入阻塞状态。

 

    这里的重量级锁指的就是传统synchronized同步。

 

    偏向锁与轻量级锁虽然可以提高有同步无竞争的性能,但是我们在实际工作中遇到的大多都是一个共享资源被多个线程访问,此时上述操作反而会多余并增加类似于CAS操作,自旋等资源开销,我们应该根据实际情况来使用上述优化,在锁竞争激烈的时候我们其实可以用参数-XX:-UseBiasedLocking来禁止偏向锁优化来提升性能。

 

 

配置VS Code使用Linux服务器上的Matlab 0、需求 Linux服务器上安装有Matlab 无图形界面,只能使用命令行工具,编辑文件不方便 1、VS Code插件安装 在扩展商店中搜索matlab,会出现Matlab Extension Pack,里面有整理好的matlab扩展 这里只安装了第一排的三个扩展 2、设置(Windows、Mac的设置类似,只是不同系统的文件路径不同) 安装好扩展,重启VS Code后,进行设置 打开:文件→首选项→设置(或快捷键ctrl+,),搜索matlab,结果如下图所示;直接打开完整json配置文件(图 阅读详情

相关推荐

Android P HAL层添加HIDL实例(详细实现步骤)

Android P HAL层添加HIDL实例 本文将介绍如何在P OS上添加HIDL实例,简单增加seLinux策略使得可以在system_service调用测试,并用模拟器emulator验证。 调用过程为 APP->TestManager->TestService->ITast.hal 文章目录Android P HAL层添加HIDL实例实现过程一 、hardware部分1...

sinat_18179367的博客 1万+

synchronized锁的优化

在多线程并发中synchronized一直被成为重量级锁,但是随着JDK1.6后对其进行各种优化,包括适应性自旋,锁消除,锁粗化,轻量级锁。偏向锁,有些情况下它就并不难笨重了。Java中每一个对象都可以作为锁,具体表现为(1) 对于普通同步方法,锁就是当前实例对象 (2) 对于静态同步方法, 锁就是当前类的Class对象 (3) 对于同步方法块,锁就是synchronized括号里配置的对象在J

拯救地球好累 522

在 ABAP Cloud 里优雅读取与解析 XML:用 sXML Reader 把接口数据落成结构化 ABAP

ABAP Cloud中XML解析实践 摘要:本文介绍了在ABAP Cloud环境下解析XML数据的最佳实践。针对企业系统中常见的XML格式数据,文章推荐使用sXML库中的CL_SXML_STRING_READER进行流式解析,而非传统的DOM方式。重点解析了命名空间(Namespace)、属性(Attribute)和CDATA等关键概念的处理方法,并比较了两种读取属性的策略:通扫所有属性(NEXT_ATTRIBUTE)和精准取值(GET_ATTRIBUTE_VALUE)。文章提供了完整的ABAP Cloud

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 187

15、JAVA中synchronized优化

在Java6之后自旋锁时自适应的,比如对象刚刚的一次自旋操作成功过,那么认为这次自旋成功的可能性会高,就多自旋几次;反之,就会少自旋甚至不自旋,总之,比较智能。另外JVM可能会做如下优化,把多次append的加锁操作粗化为一次(因为都是对同一个对象佳作,没必要重入多次)synchronized优化;

weixin_75149683的博客 1016

Ansys Lumerical双层扭曲液晶偏振光栅仿真:宽角度衍射效率优化

Ansys Lumerical双层扭曲液晶偏振光栅仿真研究 摘要 本文采用Ansys Lumerical软件平台,对双层扭曲液晶偏振光栅的宽角度衍射特性进行系统仿真研究。针对6μm周期的液晶光栅结构,以1050nm、1064nm和1550nm三个近红外波段为研究对象,在±40°入射角范围内优化平均衍射效率。研究基于液晶材料的双折射特性(Δn=0.135),通过构建两层扭曲方向相反的液晶层结构,扫描0-90°单层扭曲角度和不同厚度参数,利用RCWA求解器进行严格耦合波分析~~~~~~~

huanghm88的专栏 164

UDF学习(二)基础数据类型与常见宏

thread_loop_c (t,d) 必须与begin_c_loop (c,t)同时使用,但begin_c_loop (c,t)不一定与thread_loop_c (t,d)同时使用。同理thread_loop_f(t,d)必须与begin_f_loop (c,t)同时使用,但begin_f_loop (c,t)不一定与thread_loop_f(t,d)同时使用。begin_c_loop (c,t) 在计算域内对网格单元进行循环。c_face_loop (c,t)遍历网格单元上的所有网格面。

weixin_44386973的博客 855

多线程 第四节 Java 虚拟机对 synchronized 的优化

1、 synchronized 相对于 volatile 是重量了很多,因此在以前很让人诟病,但是从 JDK 1.6 版本以后为了减少获得锁和释放锁带来的性能消耗而引入了偏向锁和轻量级锁,以及锁的存储结构和升级过程。 2、 在 Java SE 1.6 中,锁一共有4种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态 3、 这四种状态会随着竞争情况逐渐升级。锁可以升级但不能降级 4、 这是因为,自旋锁无法预知到底会空循环几个时钟周期,并且会很消耗 CPU,为了避免这种无用的自旋操作,

ellen艾琳的博客 305

数据中台:大数据平台,数据仓库(DM),数据中台之间的联系以及异同分析

大数据平台是一个技术平台。这个技术平台提供了对于大数据的分布式采集,存储,流处理和计算,实时分析等能力。在没有大数据平台前也有数据集成和管理的平台,这种平台可以实现对结构化数据本身的采集,集成和管理。 管理平台,是在原生的大数据生态的基础之上,为了更好的管理集群服务,管理集群的资源,提供灵活SRE能力和资源核算审计能力的一系列工具和合称整体架构数据中台包括数据仓库的全部内容,数据仓库为数据中台提供了数据对外提供服务的基础资源,数据中台将数据仓库建设的投入价值进行最大化,以加快数据赋能业务的速度大家都知道数据

GIS摆渡人 2131

Syschronized的底层实现原理以及各种锁的理解

      java中每个对象都可作为锁,锁有四种级别,按照量级从轻到重分为:无锁、偏向锁、轻量级锁、重量级锁。每个对象一开始都是无锁的,随着线程间争夺锁,越激烈,锁的级别越高,并且锁只能升级不能降级。 java对象头  锁的实现机制与java对象头息息相关,锁的所有信息,都记录在java的对象头中。用2字(32位JVM中1字=32bit=4baye)存储对象头,如果是数组类型使用3字存储(还...

菜鸟不会飞 2898

yolov26改进 | 检测头篇 | 利用渐近特征金字塔网络AFPN改进yolov26检测头融合P2网络结构(让小目标无所遁形,全网独家首发)

本文介绍一种基于AFPN渐近特征金字塔网络改进的YOLOv26四检测头Detect_FPN。AFPN通过逐级融合底层细节、中层结构与高层语义特征,缩小不同尺度特征之间的语义差距,减少直接融合带来的信息冲突,使检测头获得更稳定、更充分的多尺度表达。本文进一步增加高分辨率小目标检测分支,强化对微小目标、密集目标和复杂背景目标的感知能力,适合工业缺陷、遥感及无人机等场景。文中将展示基础模型与改进模型的训练对比结果,并提供完整代码、配置文件、模块注册方法及Codex修改思路,方便直接复现和二次创新。

Snu77的博客 369

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Java 虚拟机对 synchronized 锁的优化

一、volatile 与 synchronized 关键字 的原理           Java代码首先会被编译成字节码文件。字节码文件被加载到JVM中,JVM将字节码翻译成汇编指令,从而在CPU中执行。         谈到volatile关键字,就会想到两点:         (1)让变量在多个线程之间可见,并且强制线程从公共堆栈中取得变量的值(常见的从变量和线程的角度分别阐释)。 ...

大宇的博客,欢迎访问 763

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

java虚拟机 synchronized锁优化

自旋锁与自适应自旋 互斥同步的时候,挂起线程和恢复线程的操作都需要转入内核态中完成,这些操作给系统的并发带来很大压力。同步虚拟机团队发现许多应用上锁定状态的维持时间很短,为了这段时间去挂起和恢复线程并不值得。所以当一个线程请求另一个线程的锁时,我们可以让请求线程稍等一下,但不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁,我们只需让请求线程执行一个忙循环(自旋),这就是所谓的自旋锁。

y124675160的专栏 493

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Java虚拟机13:互斥同步、锁优化及synchronized和volatile

互斥同步 互斥同步(Mutual Exclusion & Synchronization)是常见的一种并发正确性保证手段。同步是指子啊多个线程并发访问共享数据时,保证共享数据在同一时刻只能被一个(或者是一些,使用信号量的时候)线程使用。而互斥是实现同步的一种手段,临界区(Critial Section)、互斥量(Mutex)和信号量(Semaphore)都是主要的互斥实现方式。因此,在这四个

TinnnnnnY 730

Java虚拟机17:互斥同步、锁优化及synchronized和volatile

互斥同步 互斥同步(Mutual Exclusion & Synchronization)是常见的一种并发正确性保证手段。同步是指子啊多个线程并发访问共享数据时,保证共享数据在同一时刻只能被一个(或者是一些,使用信号量的时候)线程使用。而互斥是实现同步的一种手段,临界区(Critial Section)、互斥量(Mutex)和信号量(Semaphore)都是主要的互斥实现方式。因此,在这...

LMAKE_nbsp的博客 299

Java多线程编程-(11)-从volatile和synchronized的底层实现原理看Java虚拟机对锁优化所做的努力

原文出自 : https://blog.youkuaiyun.com/xlgen157387/article/details/78327228 一、背景 对于Java来说我们知道,Java代码首先会编译成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上进行执行。 Java中所使用的并发机制依赖于JVM的实现和CPU的指令。 下边我们对常见的实现同步的两...

makesailing的博客 197

Java 虚拟机:互斥同步、锁优化及synchronized和volatile

互斥同步 互斥同步(Mutual Exclusion & Synchronization)是常见的一种并发正确性保证手段。同步是指子啊多个线程并发访问共享数据时,保证共享数据在同一时刻只能被一个(或者是一些,使用信号量的时候)线程使用。而互斥是实现同步的一种手段,临界区(Critial Section)、互斥量(Mutex)和信号量(Semaphore)都是主要的互斥实现方式。因此,在这...

weixin_33893473的博客 119

Java 虚拟机 13:互斥同步、锁优化及synchronized和volatile

原文出处: 五月的仓颉互斥同步互斥同步(Mutual Exclusion & Synchronization)是常见的一种并发正确性保证手段。同步是指子啊多个线程并发访问共享数据时,保证共享数据在同一时刻只能被一个(或者是一些,使用信号量的时候)线程使用。而互斥是实现同步的一种手段,临界区(Critial Section)、互斥量(Mutex)和信号量(Semaphore)都是主要的互斥实...

chenshiyang0806的博客 215

优时同步2.7 java_Java虚拟机13:互斥同步、锁优化及synchronized和volatile

互斥同步互斥同步(Mutual Exclusion & Synchronization)是常见的一种并发正确性保证手段。同步是指子啊多个线程并发访问共享数据时,保证共享数据在同一时刻只能被一个(或者是一些,使用信号量的时候)线程使用。而互斥是实现同步的一种手段,临界区(Critial Section)、互斥量(Mutex)和信号量(Semaphore)都是主要的互斥实现方式。因此,在这四个...

weixin_39587246的博客 115
上一篇: Java 同步代码块synchronized
下一篇: Red Hat yum无法使用解决方案 替换为centOS yum 使用163源
JavaBoy王皓
博客等级 码龄11年 23粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值