首页 > 其他分享 >一文讲清楚synchronized原理---每周一更系列

一文讲清楚synchronized原理---每周一更系列

时间:2024-08-03 21:06:56浏览次数:8  
标签:讲清楚 Monitor synchronized 对象 --- 线程 数据结构 轻量级

synchronized是Java提供的原子性内置锁,这种内置的并且使用者看不到的锁也被称为监视器锁。

synchronized通过在代码块前后加上monitorenter和monitorexit字节码指令用于实现进入和退出。

如果是同步方法,则是打上标记,隐式的使用monitorenter和monitorexit字节码指令。

在jdk1.5之前,加锁和释放锁是由操作系统来实现的,系统调用涉及到上下文切换,性能消耗极高,多以当时synchronized性能极差并且是公认的重量级锁。

在jdk1.6之后,引入了偏向锁和轻量级锁两个概念,通过锁升级策略来解决性能问题。

为了讲清楚Synchronized工作原理,需要理解以下几个问题:

  • 程序 = 数据结构 + 算法,锁也是属于一种程序,所以它应该有对应的数据结构 + 算法。

  • Java对象内存布局,即synchronized使用了怎么样的数据结构?

    每个Java对象在内存中的布局通常分为三部分:对象头、实例数据、对齐填充。对象头中包含Mark Word和Class Point

    重点就是Mark Word,它包含一下信息:

    • 哈希码

    • GC标志

    • 锁标志位:判断当前对象处于什么锁状态(无锁、偏向锁、轻量级锁、重量级锁)

    • 偏向锁的线程ID

    • 轻量级锁的栈地址指针

    • 重量级锁的Monitor指针

  • 怎么理解每个对象都有成为锁的潜质?

    由于每个对象都有Mark Word,都可以存储锁状态,都是可以支撑锁算法的数据结构,所以每个对象都有成为锁的潜质。

  • 对象是怎么通过Mark Word成为一把锁的?即怎么使用这个数据结构标识不同的锁状态?

    无锁:当一个对象新建时,没有被任何对象锁定,此时锁标志位01

    偏向锁:第一个线程获取对象锁,锁标志位01,偏向标志位标记为1,并在对象头中记录锁的线程ID,如果没有竞争,下次直接根据ID直接获取,即可重入,避免了频繁CAS。

    轻量级锁:发现锁竞争,即两个线程以上时,偏向锁取消,升级为轻量级锁,此时线程会在栈帧中创建一个锁记录,并尝试通过CAS将对象头的轻量级锁栈地址指针指向锁记录,成功则获取到了锁。锁记录中记录了重入次数,同时修改锁标志位,记录锁状态。

    重量级锁:当竞争激烈,CAS次数超过重试阈值时,JVM决定升级为重量级锁,此时JVM创建Monitor对象或者使用已有的Monitor对象,并将Monitor指针指向Monitor对象,后续交由操作系统进行调度。

    Monitor对象

    Monitor对象不是原始Java对象,而是JVM内部使用的数据结构。它用于实现重量级锁的管理,通常包含以下字段:

    1. Owner:当前持有锁的线程。
    2. Recursion Count:重入计数器,记录当前线程的重入次数。
    3. Entry List:等待获取锁的线程队列。
    4. Wait Set:等待某个条件的线程队列(通常用于waitnotify机制)。

    线程进入同步代码块时,首先进入entryList,获取到锁后就更改Owner,并且计数器加1。

    如果线程wait了,就会释放锁,释放锁之后就进入Wait Set,只有通过notify或者notifyAll才能唤醒,唤醒之后又进入entryList排队竞争锁。

    获取到锁的线程执行完毕就释放锁,计数器减1,当前线程Owner置Null

标签:讲清楚,Monitor,synchronized,对象,---,线程,数据结构,轻量级
From: https://www.cnblogs.com/lilizzyy/p/18341094

相关文章

  • Ubuntu24.04-EDA2018.06
    0.PreperationWindows11VMwareWorkstation17ProUbuntu24.04VCS_VERDI2018.061.Install1.在ubuntu中新建synopsys文件夹cd/home/wenmkdirsynopsys#在/home/wen/目录下新建synopsys文件夹sudochmod777synopsys/#添加权限2.将windows文件下载到......
  • Android开发 - Fragment 类详解
    Fragment是什么Fragment是Android开发中的一种模块化组件,一个抽象类,允许开发者将一个Activity分解成多个独立的、可重用的部分。每个Fragment都有自己的生命周期和用户界面,可以独立管理自己的UI和行为,它们可以动态地添加、移除或替换,从而提高应用程序的灵活性和可维护......
  • Rockchip rk3588-Android tv-红外接收调试
    参考:https://wiki.friendlyelec.com/wiki/index.php/NanoPC-T6/zh#ADB.E7.9A.84.E4.BD.BF.E7.94.A8https://www.cnblogs.com/ningci/p/15256839.htmlhttps://wiki.t-firefly.com/zh_CN/Firefly-RK3288/driver_ir.html开发板:Nanopc-T6系统:Android12TV工具:Xshell7、开心电视......
  • 灰狼优化算法(GWO)与长短期记忆网络(LSTM)结合的预测模型(GWO-LSTM)及其Python和MATLAB实现
    ####一、背景在现代数据科学和人工智能领域,预测模型的准确性和效率是研究者和工程师不断追求的目标,尤其是在时间序列预测、金融市场分析、气象预测等领域。长短期记忆(LSTM)网络是一种解决传统递归神经网络(RNN)在长序列学习中存在的梯度消失和爆炸问题的有效模型。LSTM能够保持......
  • Docker Hub 和 registry-1.docker.io 的关系
     registry-1.docker.io是DockerHub的底层注册表(Registry)地址,用于存储和管理Docker镜像。在Docker中,一个注册表(Registry)是存储Docker镜像的地方,而registry-1.docker.io是DockerHub的注册表地址之一。DockerHub和registry-1.docker.io的关系:DockerHub:Do......
  • 灰狼优化算法(GWO)与门控循环单元(GRU)结合的预测模型(GWO-GRU)及其Python和MATLAB实现
    ####一、背景深度学习已成为解决复杂时序数据预测问题的重要工具。在众多神经网络架构中,门控循环单元(GatedRecurrentUnit,GRU)凭借其在捕捉时间序列数据中的长程依赖性和相对较低的计算复杂度而受到广泛关注。此外,优化算法在深度学习模型的训练中扮演着至关重要的角色。灰......
  • 打造前端开发的利器--NPM
    个人名片......
  • Android开发 - DetailFragment 类解析
    DetailFragment是什么DetailFragment专门用于显示详细信息。当用户在主界面(例如一个列表)中选择某个项时,应用会使用DetailFragment显示该项的详细信息。它通常与主界面的Fragment协同工作,形成一个主从结构(Master-Detail)使用场景新闻应用:主界面显示新闻列表,DetailFrag......
  • 嵌入式学习---DAY18:shell脚本
    shell脚本文件进程网络HtmlDbshell脚本是一系列shell命令的集合。  shell  命令解释器shell编程:解释型语言、边翻译边执行、擅长文件处理,操作系统管理、开发效率高  cp 1  2、执、效率低、移植性好C语言:编译型语言、先编译再执行、擅长数据计算和数据处理、开发......
  • 在这个只有病人去的场所,你看到了哪些意料之外的举动?--医者仁心:医院里的温情奇迹
    在这个只有病人去的场所,你看到了哪些意料之外的举动?--医者仁心:医院里的温情奇迹在繁忙与喧嚣交织的医院里,每一天都上演着生与死的较量,但在这片看似冷漠的土地上,却也悄然绽放着无数温暖人心的花朵。今天,就让我们一起走进这些感人至深的故事,感受那些医患之间、人与人之间最......