0

0

Java中的synchronized锁膨胀机制怎么实现

WBOY

WBOY

发布时间:2023-04-28 17:13:13

|

1795人浏览过

|

来源于亿速云

转载

    synchronized

    在 jdk 1.5 时,synchronized 需要调用监视器锁(monitor)来实现,监视器锁本质上又是依赖于底层的操作系统的 mutex lock(互斥锁)实现的,互斥锁在进行释放和获取的时候,需要从用户态转换到内核态,这样就造成了很高的成本,也需要较长的执行时间,这种依赖于操作系统 mutex lock 实现的锁我们称之为“重量级锁”。

    什么是用户态和内核态?

    用户态(User Mode):当进程在执行用户自己的代码时,则称其处于用户运行态。 内核态(Kernel Mode):当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态,此时处理器处于特权级最高的内核代码中执行。 

    Java中的synchronized锁膨胀机制怎么实现

    为什么分内核态和用户态?

    假设没有内核态和用户态之分,程序就可以随意读写硬件资源了,比如随意读写和分配内存,这样如果程序员一不小心将不适当的内容写到了不该写的地方,很可能就会导致系统崩溃。

    而有了用户态和内核态的区分之后,程序在执行某个操作时会进行一系列的验证和检验之后,确认没问题之后才可以正常的操作资源,这样就不会担心一不小心就把系统搞坏的情况了,也就是有了内核态和用户态的区分之后可以让程序更加安全的运行,但同时两种形态的切换会导致一定的性能开销。

    立即学习Java免费学习笔记(深入)”;

    锁膨胀

    在 JDK 1.6 时,为了解决获取锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”的状态,此时 synchronized 的状态总共有以下 4 种:

    • 无锁

    • 偏向锁

    • 轻量级锁

    • 重量级锁

    锁的级别按照上述先后顺序依次升级,我们把这个升级的过程称之为“锁膨胀”。 

    Java中的synchronized锁膨胀机制怎么实现

    PS:到现在为止,锁的升级是单向的,也就是说只能从低到高升级(无锁 -> 偏向锁 -> 轻量锁锁 -> 重量级锁),不会出现锁降级的情况。

    锁膨胀为什么能优化 synchronized 的性能?当我们了解了这些锁状态之后自然就会有答案,下面我们一起来看。

    偏向锁

    HotSpot 作者经过研究实践发现,在大多数情况下,锁不存在多线程竞争,总是由同一线程多次获得的,为了让线程获得锁的代价更低,于是就引进了偏向锁。

    偏向锁(Biased Locking)指的是,它会偏向于第一个访问锁的线程,如果在运行过程中,同步锁只有一个线程访问,不存在多线程争用的情况,则线程是不需要触发同步的,这种情况下会给线程加一个偏向锁。

    偏向锁执行流程

    当一个线程访问同步代码块并获取锁时,会在对象头的 Mark Word 里存储锁偏向的线程 ID,在线程进入和退出同步块时不再通过 CAS 操作来加锁和解锁,而是检测 Mark Word 里是否存储着指向当前线程的偏向锁,如果 Mark Word 中的线程 ID 和访问的线程 ID 一致,则可以直接进入同步块进行代码执行,如果线程 ID 不同,则使用 CAS 尝试获取锁,如果获取成功则进入同步块执行代码,否则会将锁的状态升级为轻量级锁。

    偏向锁的优点

    偏向锁是为了在无多线程竞争的情况下,尽量减少不必要的锁切换而设计的,因为锁的获取及释放要依赖多次 CAS 原子指令,而偏向锁只需要在置换线程 ID 的时候执行一次 CAS 原子指令即可。

    Mark Word 扩展知识:内存布局

    在 HotSpot 虚拟机中,对象在内存中存储的布局可以分为以下 3 个区域:

    AVCLabs
    AVCLabs

    AI移除视频背景,100%自动和免费

    下载
    • 对象头(Header)

    • 实例数据(Instance Data)

    • 对齐填充(Padding)

    对象头中又包含了:

    • Mark Word(标记字段):我们的偏向锁信息就是存储在此区域的

    • Klass Pointer(Class 对象指针)

    对象在内存中的布局如下: 

    Java中的synchronized锁膨胀机制怎么实现

     在 JDK 1.6 中默认是开启偏向锁的,可以通过“-XX:-UseBiasedLocking=false”命令来禁用偏向锁。

    轻量级锁

    引入轻量级锁的目的是在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统 Mutex Lock(互斥锁)产生的性能消耗。如果使用 Mutex Lock 每次获取锁和释放锁的操作都会带来用户态和内核态的切换,这样系统的性能开销是很大的。

    当关闭偏向锁或者多个线程竞争偏向锁时就会导致偏向锁升级为轻量级锁,轻量级锁的获取和释放都通过 CAS 完成的,其中锁获取可能会通过一定次数的自旋来完成。

    注意事项

    需要强调一点:轻量级锁并不是用来代替重量级锁的,它的本意是在没有多线程竞争的前提下,减少传统的重量级锁使用产生的性能消耗。轻量级锁所适应的场景是线程交替执行同步块的情况,如果同一时间多个线程同时访问时,就会导致轻量级锁膨胀为重量级锁。

    重量级锁

    synchronized 是依赖监视器 Monitor 实现方法同步或代码块同步的,代码块同步使用的是 monitorenter 和 monitorexit 指令来实现的,monitorenter 指令是在编译后插入到同步代码块的开始位置,而 monitorexit 是插入到方法结束处和异常处的,任何对象都有一个 Monitor 与之关联,当且一个 Monitor 被持有后,它将处于锁定状态。

    如以下加锁代码:

    public class SynchronizedToMonitorExample {
        public static void main(String[] args) {
            int count = 0;
            synchronized (SynchronizedToMonitorExample.class) {
                for (int i = 0; i < 10; i++) {
                    count++;
                }
            }
            System.out.println(count);
        }
    }

    当我们将上述代码编译成字节码之后,它的内容是这样的: 

    Java中的synchronized锁膨胀机制怎么实现

    从上述结果可以看出,在 main 方法的执行中多个 monitorenter 和 monitorexit 的指令,由此可知 synchronized 是依赖 Monitor 监视器锁实现的,而监视器锁又是依赖操作系统的互斥锁(Mutex Lock),互斥锁在每次获取和释放锁时,都会带来用户态和内核态的切换,这样就增加了系统的性能开销。

    相关文章

    java速学教程(入门到精通)
    java速学教程(入门到精通)

    java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

    下载

    相关标签:

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    热门AI工具

    更多
    DeepSeek
    DeepSeek

    幻方量化公司旗下的开源大模型平台

    豆包大模型
    豆包大模型

    字节跳动自主研发的一系列大型语言模型

    通义千问
    通义千问

    阿里巴巴推出的全能AI助手

    腾讯元宝
    腾讯元宝

    腾讯混元平台推出的AI助手

    文心一言
    文心一言

    文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

    讯飞写作
    讯飞写作

    基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

    即梦AI
    即梦AI

    一站式AI创作平台,免费AI图片和视频生成。

    ChatGPT
    ChatGPT

    最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

    相关专题

    更多
    Python 自然语言处理(NLP)基础与实战
    Python 自然语言处理(NLP)基础与实战

    本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

    10

    2026.01.27

    拼多多赚钱的5种方法 拼多多赚钱的5种方法
    拼多多赚钱的5种方法 拼多多赚钱的5种方法

    在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

    109

    2026.01.26

    edge浏览器怎样设置主页 edge浏览器自定义设置教程
    edge浏览器怎样设置主页 edge浏览器自定义设置教程

    在Edge浏览器中设置主页,请依次点击右上角“...”图标 > 设置 > 开始、主页和新建标签页。在“Microsoft Edge 启动时”选择“打开以下页面”,点击“添加新页面”并输入网址。若要使用主页按钮,需在“外观”设置中开启“显示主页按钮”并设定网址。

    16

    2026.01.26

    苹果官方查询网站 苹果手机正品激活查询入口
    苹果官方查询网站 苹果手机正品激活查询入口

    苹果官方查询网站主要通过 checkcoverage.apple.com/cn/zh/ 进行,可用于查询序列号(SN)对应的保修状态、激活日期及技术支持服务。此外,查找丢失设备请使用 iCloud.com/find,购买信息与物流可访问 Apple (中国大陆) 订单状态页面。

    136

    2026.01.26

    npd人格什么意思 npd人格有什么特征
    npd人格什么意思 npd人格有什么特征

    NPD(Narcissistic Personality Disorder)即自恋型人格障碍,是一种心理健康问题,特点是极度夸大自我重要性、需要过度赞美与关注,同时极度缺乏共情能力,背后常掩藏着低自尊和不安全感,影响人际关系、工作和生活,通常在青少年时期开始显现,需由专业人士诊断。

    7

    2026.01.26

    windows安全中心怎么关闭 windows安全中心怎么执行操作
    windows安全中心怎么关闭 windows安全中心怎么执行操作

    关闭Windows安全中心(Windows Defender)可通过系统设置暂时关闭,或使用组策略/注册表永久关闭。最简单的方法是:进入设置 > 隐私和安全性 > Windows安全中心 > 病毒和威胁防护 > 管理设置,将实时保护等选项关闭。

    6

    2026.01.26

    2026年春运抢票攻略大全 春运抢票攻略教你三招手【技巧】
    2026年春运抢票攻略大全 春运抢票攻略教你三招手【技巧】

    铁路12306提供起售时间查询、起售提醒、购票预填、候补购票及误购限时免费退票五项服务,并强调官方渠道唯一性与信息安全。

    122

    2026.01.26

    个人所得税税率表2026 个人所得税率最新税率表
    个人所得税税率表2026 个人所得税率最新税率表

    以工资薪金所得为例,应纳税额 = 应纳税所得额 × 税率 - 速算扣除数。应纳税所得额 = 月度收入 - 5000 元 - 专项扣除 - 专项附加扣除 - 依法确定的其他扣除。假设某员工月工资 10000 元,专项扣除 1000 元,专项附加扣除 2000 元,当月应纳税所得额为 10000 - 5000 - 1000 - 2000 = 2000 元,对应税率为 3%,速算扣除数为 0,则当月应纳税额为 2000×3% = 60 元。

    35

    2026.01.26

    oppo云服务官网登录入口 oppo云服务登录手机版
    oppo云服务官网登录入口 oppo云服务登录手机版

    oppo云服务https://cloud.oppo.com/可以在云端安全存储您的照片、视频、联系人、便签等重要数据。当您的手机数据意外丢失或者需要更换手机时,可以随时将这些存储在云端的数据快速恢复到手机中。

    121

    2026.01.26

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    Kotlin 教程
    Kotlin 教程

    共23课时 | 2.9万人学习

    C# 教程
    C# 教程

    共94课时 | 7.7万人学习

    Java 教程
    Java 教程

    共578课时 | 51.9万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号