当前位置: 首页 > article >正文

Synchronized关键字的底层原理

Synchronized实现

Synchronized创建的时候一个互斥的对象锁,每次只有一个线程可以获取该锁。

其底层主要是基于Monitor实现的,在对象的对象头中存储了MarkWord存储的就是Monitor的地址。

 对象的内存结构

对象在内存中存储主要分为三个部分:对象头,实例数据,对齐填充。 

对象头:MarkWord用于存储锁的信息,Klass Word用于存储对象的类型。

  • 无锁状态:hashcode(25位)+ 对象分代年龄(4位,不是重点)+ 偏向锁标识(1位)+ 锁标识(2位)
  • 偏向锁:thread(23位,线程id)+ 偏向时间戳(2位,不是重点)+ 偏向锁标识(1位)+ 锁标识(2位)
  • 轻量级锁:对应线程的栈中指向锁记录的指针。(30位)
  • 重量级锁:对应monitor的地址。(30位)

实例数据:用于存储对象中成员变量的信息。 

对齐填充:不是重点,主要是为了保证长度是8的整数倍。

Monitor(重量级锁)

其中包括三个部分:waitSet,entryList,owner。

owner:存储当前获得锁的线程的id。

enrtyList:存储没有获取到锁的线程id的集合,这些线程处于堵塞状态。

waitList:存储处于等待的线程的集合,通常这些线程调用了wait方法。

当线程要获取锁的时候会先去owner判断是否有线程存在,如果没有的话,直接获取锁并将线程id写入owner,反之写入entryList。

轻量级锁

重量级锁主要使用在线程竞争的时候,且重量级锁涉及进程的上下文切换,效率比较低下,在没有线程竞争且不同线程交替执行的时候,推荐使用轻量级锁。

上锁

在线程栈中创建一个锁记录,锁记录中包含 锁记录地址和指向对象的指针两个部分。通过CAS指令将锁记录地址和MarkWord中的地址进行交换

1.如果对象处于无锁状态则说明获取锁成功,且获取的是轻量级锁。

2.如果对象已经有锁了,这此时就是锁的重入,会继续创建锁记录,且也会进行做CAS指令,但是

 记录锁的地址为null。起到锁重入计数效果。

3.如果CAS指令失败了,则会直接使用重量级锁。

解锁

1.遍历线程栈,找到对象指针指向锁对象的锁记录。

2.如果锁记录中的MarkWord的值为null,说明这是一次锁重入操作,直接将锁记录中的指向对象的地址设置为null。

3.如果锁记录中的MarkWord的值不为null,我们就通过CAS指令将锁对象中的MarkWord恢复成无锁状态。

偏向锁

类是轻量级锁,但是在做锁的重入的时候不会使用CAS指令,而是直接判断thread的id是否相同,相同就表示没有竞争。减少了CAS指令操作。适合使用在长时间只有一个线程使用锁

所有锁一但发生了冲突都会变成重量级锁。 

三种锁的使用场景


http://www.kler.cn/news/156409.html

相关文章:

  • 关系型数据库的数据隔离级别Read Committed与Repeatable Read
  • springboot(ssm 二手图书交易系统 图书销售系统Java(codeLW)
  • 删除PPT文件的备注内容
  • python爬虫之创建属于自己的ip代理池
  • 行业分析:2023年木炭行业市场需求及发展前景
  • 鸿蒙基础入门与高频知识点梳理
  • 2.1 Linux C 编程
  • 在一个没有超级用户的mongodb 生产库上如何添加超级用户
  • 【每日OJ —— 110. 平衡二叉树】
  • uniapp微信小程序解决绘制polygon结束时的问题
  • pdfjs,pdf懒加载
  • 高效且实用的表单配置方式:低代码表单上传文件后即刻回显
  • ruoyi+Hadoop+hbase实现大数据存储查询
  • 400页Python学习PDF笔记,全面总结零基础入门看这一篇足够了
  • 《微信小程序开发从入门到实战》学习四十
  • 大数据|计算机毕业设计——基于Django协同过滤算法的房源可视化分析推荐系统的设计与实现
  • flutter开发实战-readmore长文本展开和收缩控件
  • C++学习 --函数对象
  • 线上超市小程序可以做什么活动_提升用户参与度与购物体验
  • 活动回顾|德州仪器嵌入式技术创新发展研讨会(上海站)成功举办,信驰达科技携手TI推动技术创新
  • 学习-java多线程面试题
  • 在 Linux 上修改 Oracle 控制文件、日志文件和数据文件的目录的脚本
  • Rust UI开发(五):iced中如何进行页面布局(pick_list的使用)?(串口调试助手)
  • (一)舒尔特表练习记
  • 新手村之SQL——函数多表联结
  • rman SBT_TAPE NFS disk 模拟NBU带库 FRA
  • Android跨进程通信,binder,native层,服务端在servicemanager注册服务
  • 【FAQ】运动健康服务端侧数据常见问题及解答
  • Android 透明度颜色值对照表
  • Apache Flink(六):Apache Flink快速入门 - Flink案例实现