synchronized原理

当线程释放锁,JMM会把线程对应的本地的内存中的共享变量刷新到内存中
当线程获取锁,JMM会帮其他线程中对应的本地的内存中的共享变量设置未无效,从而监视器保护的临界区的代码必须从内存中读取共享变量。(临界区为锁之间的代码)

synchronized特性

  • 原子性:在一个段内,要么全部执行,并且不会被其他线程干扰
  • 可见性:当一个线程获取了锁时,其他线程对该锁的状态时可见性的,并且当释放锁后,资源会同步到内存中,其他线程对其又是可见性
  • 有序性:在一个段内,重排是没有影响,如果多个线程重排是有影响,synchronized保证了在同一时刻只能有一个线程操作。
  • 重入性:一个线程获取锁,其他锁不能在获取,但是这个线程再次获取锁,依旧能够获取锁并进入,不过其中的标识会+1。

synchronized锁的底层实现

Java对象模型

jvm加载一个类,会创建一个instanceKlass,保存在方法区中,new时创建一个对象,对象包含两个部分,对象头实例数据部分。
对象头包含两个部分:

  • Mark word一些运行时数据,包括hash code,锁状态标识,线程持有的锁等信息。
  • klass Point是类型指针指向对象的类元数据,JVM通过该指针确定该对象是哪个类的实例

对象的实例(instantOopDesc)保存在堆上,对象的元数据(instantKlass)保存在方法区,对象的引用保存在栈上。

Monitor

为了解决线程的安全问题,Java提供了同步机制,互斥锁机制。这个机制保证了同一时刻只有一个线程访问共享资源。这个机制的保障来源于Monitor。
每个对象内置了一个Monitor对象,Monitor相当于一个许可证,拿个这个monitor就可以进入操作,否则进行等待。
ObjectMonitor对象结构:

  • _owner: 持有ObjectMonitor对象的线程
  • _WaitSet: 持有锁的线程调用Wait方法会加入到WaitSet队列中
  • _EntryList:存放于等待锁状态的线程队列
  • _recursions:锁的重入次数

synchronized 的原理

对方法和类,方法中会添加一个标识flags,类的话在进入添加一个monitorEnter和monitorExit,进入时,会对标识+1,退出时对标识-1。其他获取锁时,会去竞争该资源,如果已经有了标识,则会进行等待。

同步代码块

在代码快中进入时,添加monitorEnter,标识进入了同步代码块中,其它线程进入时,进行等待,在代码块退出时,添加了monitorExit,其它线程可以进入到同步代码块中
image.png
同步代码块字节码
image.png

方法同步

synchronized方法则会被编译成普通的方法调用和返回指令,如:invokevirtual、areturn指令;
在JVM字节码层面并没有任何特别的指令来实现方法的同步,而是在Class文件的方法表中,将该方法的access_flags字段中的synchronized标志位置1,表示该方法是同步方法,并使用调用该方法所属的类实例对象,或该方法所属的Class在JVM的内部表示对象Klass做为锁对象。

锁的类型

  • 不需要monitor entry和monitor exist
  • 锁粗化:当编译器有代码连续多次加锁释放锁时会合并为一个锁
  • 偏向锁:如果大概只有一个线程加锁会给这个线程维护一个bias偏好,后面加锁基于bias不需要cas
  • 轻量级锁:当偏向锁加锁失败,mark word有一个轻量级的指针来直接指向持有锁的线程然后判断是不是自己加的锁
  • 重量级锁:当获取锁时锁被其他线程占用则升级为重量级锁
  • 自适应自旋锁:当线程获取锁失败后进入自旋状态去检查count变量值,不进行线程上下文切换因为锁等待时间会很短,而不是直接进入到entrylist中(从用户态到内核态)默认开启,自旋次数10次,jdk1.6之后加入了自适应的自旋锁通过上次自旋获取锁的时间和次数来解决

当一个线程获取锁,则会进入到偏向锁,第二线程竞争锁时,则锁进行膨胀为轻量级锁,当多个线程进行竞争是,则会进入到重量级锁。在后续jdk中,偏向锁禁用掉了或者是被废弃了。

wait和notify机制

**wait()**最终调用ObjectMonitor的wait方法,则会将当前线程封装成ObjectMonitor的对象node,通过ObjectMonitor::AddWaiter方法,将其添加到_WaitSet方法中。最后调用ObjectMonitor::exit方法放弃当前CPU,底层是调用park线程挂起。
notify方法,如果_WaitSet为空,则立刻返回,如果_WaitSet有值,将一个node取出放入到ObjectMonitor的_EntryList中,这样就可让他们竞争锁资源,这里会是进入到自旋中。

image.png

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

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

相关文章

3D模型可视化引擎HOOPS Communicator与Visualize的统一化文件加载解决方案

在当今数字化时代,3D可视化技术已成为工程设计、建筑规划和游戏开发等多个领域的核心技术。Tech Soft 3D公司凭借其创新的HOOPS Communicator和HOOPS Visualize两款开发包,分别针对Web端和桌面端提供了强大的3D可视化解决方案。然而,由于两者…

第三集《唯识与净土》

和尚尼慈悲!诸位法师、诸位居士,阿弥陀佛! 请大家打开讲义第六面,三、业果强弱。 我们身为一个有情众生,在我们的生命当中,我们曾经出现过很多痛苦的果报,当然也出现过很多安乐的果报&#xff0…

c语言回顾-结构体(2)

前言 前面讲了结构体的概念,定义,赋值,访问等知识,本节内容小编将讲解结构体的内存大小的计算以及通过结构体实现位段,话不多说,直接上干货!!! 1.结构体内存对齐 说到计…

物联网技术-第3章物联网感知技术-3.2定位技术

目录 1.1位置信息和位置服务 1.1.1位置信息 1.1.2位置服务 1.2主流定位系统 1.2.1卫星定位系统(Satellite Positioning Systems) 1.2.2移动通信蜂窝基站定位(Cellular Triangulation or Advanced Forward Link Trilateration&#xff09…

大学物理绪论组收集和分析

目录 ​编辑 随机误差的估计 算术平均值的标准偏差 不确定度(Uncertainty)是测量学中的一个重要概念,用于表示测量结果的可靠程度。它反映了测量值可能偏离真值(即被测量的客观真实值)的程度。 A类不确定度的计算方…

cephfs的形式使用ceph,大致思路

有很多方式可以使用ceph,感觉作者的大概的思路就是,把ceph当成一个存储中心,然后可以通过很多中不同的方式把数据放到这个存储中心来,也可以读取。 ceph存储数据的大致思路是,建立osd,把osd当数据存储基点…

健身小程序:智能化助力个人健身旅程

一、智能化功能的核心 健身小程序的智能化功能主要体现在以下几个方面: 智能健身计划推荐:小程序内置了先进的算法,能够根据用户的身体状况、健身目标和时间安排,智能推荐个性化的健身计划。这些计划不仅科学合理,而且…

TCP协议是安全的吗?

不安全 虽然 TCP 提供了一种可靠且高效的数据传输方式,但它不提供任何加密或身份验证机制来保护数据。因此,传输的数据可能会被未经授权的用户拦截和读取,而且其真实性无法验证。 因此,为了确保 TCP 通信的安全,必须…

ThreeJS-截屏下载pdf或者图片时白屏

JS-页面截图下载为pdf 关于如何下载为 pdf 在上面的这篇文章中有写,大家可以看下,下载图片代码在最下面 这时我们发现 three 部分是空白的如下: 这就多少有点尴尬了,这时我们习惯性的看下后台报错 是不是发现了惊喜,…

足底筋膜炎怎么治疗效果好得快

足底筋膜炎症状:疼痛是足底筋膜炎最典型和常见的症状。患者通常会感到足跟或足底区域的疼痛,这种疼痛可能表现为刺痛、钝痛或灼热感。疼痛的程度和频率因人而异,但通常会在早晨起床后或长时间休息后首次站立时最为明显。这是因为休息时足底筋…

.NET C# 读写CSV及转换DataTable

目录 .NET C# 读写CSV及转换DataTable1. 依赖库2. CSVUtil2.1 CSV 转 DataTable2.2 DataTable 转 CSV 文本2.3 DataTable 转 CSV2.4 私有方法 .NET C# 读写CSV及转换DataTable 1. 依赖库 using System.Data; using System.IO; using System.Text; using System.Text.RegularE…

eclipse宝刀未老

Theia 是一个高度可定制的、开源的、基于 Web 的集成开发环境(IDE)框架。它由 Eclipse Foundation 主导,旨在为云和本地环境提供现代化的、全功能的 IDE 解决方案。Theia 的核心目标是提供一个灵活的平台,开发者可以根据自己的需求…

睡眠脑电 | 多导睡眠图技术

摘要 多导睡眠图(PSG)一词由Holland等人于1974年提出,用于描述在睡眠期间同时记录、分析和解释多个生理特征。PSG是诊断睡眠障碍患者和增进我们对正常睡眠认识的重要工具。这是一个复杂的过程,应由训练有素的技术人员执行。本文回顾了多导睡眠图(PSG)的…

头歌----恶意流量监测

第一关:RE库的使用 任务描述 本关任务:编写一个能正则匹配出 ip 地址的小程序。 相关知识 为了完成本关任务,你需要掌握: re 的主要功能函数;re.search 函数;例子。 re 的主要功能函数 常用的功能函…

【设计模式之基于特性的动态路由映射模式】

在ASP.NET Core中,路由是核心功能之一,用于将HTTP请求映射到相应的控制器操作。虽然“路由驱动设计模式”是一个我刚杜撰出来的设计模式名称,但我们可以基于ASP.NET Core的路由特性,构建一种以路由为中心的设计模式。 以下是一个…

C#.Net筑基-类型系统②常见类型

01、结构体类型Struct 结构体 struct 是一种用户自定义的值类型,常用于定义一些简单(轻量)的数据结构。对于一些局部使用的数据结构,优先使用结构体,效率要高很多。 可以有构造函数,也可以没有。因此初始…

独孤思维:副业闷声发财,没有多少人希望你好

01 做副业,一定要留有余地。 害人之心不可有,防人之心不可无。 很多人,喜欢晒收益,喜欢吹嘘多牛b。 被同行盯上,看着眼红,反手就各种搞事情。 独孤经历过,也看到过很多同行被搞过。 不要公…

阿里又出AI神器,颠覆传统图像编辑,免费开源!

文章首发于公众号:X小鹿AI副业 大家好,我是程序员X小鹿,前互联网大厂程序员,自由职业2年,也一名 AIGC 爱好者,持续分享更多前沿的「AI 工具」和「AI副业玩法」,欢迎一起交流~ 最近阿里开源了 Mi…

C#面:阐述 POCO 是什么意思

POCO是“Plain Old CLR Object”的缩写,意为“普通的旧CLR对象”。它是一种编程模式,用于描述一个简单的、纯粹的C#对象,没有任何特殊的依赖或框架限制。POCO对象通常只包含属性和方法,没有任何特殊的基类或接口。 在C#中&#x…

003.Linux SSH协议工具

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉&…