【synchronized底层原理之4】锁的升级过程及比较
2019独角兽企业重金招聘Python工程师标准>>>
参考
https://blog.csdn.net/zqz_zqz/article/details/70233767
https://monkeysayhi.github.io/2018/01/02/%E6%B5%85%E8%B0%88%E5%81%8F%E5%90%91%E9%94%81%E3%80%81%E8%BD%BB%E9%87%8F%E7%BA%A7%E9%94%81%E3%80%81%E9%87%8D%E9%87%8F%E7%BA%A7%E9%94%81/
偏向锁获取过程
轻量级锁的加锁过程
轻量级锁的释放过程
释放锁线程的视角
由轻量锁切换到重量锁,是发生在轻量锁释放锁的期间,之前在获取锁的时候它拷贝了锁对象头的markword,在释放锁的时候如果它发现在它持有锁的期间有其他线程来尝试获取锁了,并且该线程对markword做了修改,两者比对发现不一致,则切换到重量锁。
因为重量级锁被修改了,所以display mark word和原来的markword不一样了。
怎么补救,就是进入mutex前,compare一下obj的markword状态。确认该markword是否被其他线程持有。
此时如果线程已经释放了markword,那么通过CAS后就可以直接进入线程,无需进入mutex,就这个作用。
尝试获取锁线程的视角
如果线程尝试获取锁的时候,轻量锁正被其他线程占有,那么它就会修改markword,修改重量级锁,表示该进入重量锁了。
还有一个注意点:等待轻量锁的线程不会阻塞,它会一直自旋等待锁,并如上所说修改markword。
这就是自旋锁,尝试获取锁的线程,在没有获得锁的时候,不被挂起,而转而去执行一个空循环,即自旋。在若干个自旋后,如果还没有获得锁,则才被挂起(进入阻塞状态),获得锁,则执行代码。
synchronized的执行过程
1. 检测Mark Word里面是不是当前线程的ID,如果是,表示当前线程处于偏向锁
2. 如果不是,则使用CAS将当前线程的ID替换Mard Word,如果成功则表示当前线程获得偏向锁,置偏向标志位1
3. 如果失败,则说明发生竞争,撤销偏向锁,进而升级为轻量级锁。
4. 当前线程使用CAS将对象头的Mark Word替换为锁记录指针,如果成功,当前线程获得锁
5. 如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。
6. 如果自旋成功则依然处于轻量级状态。
7. 如果自旋失败,则升级为重量级锁。
上面几种锁都是JVM自己内部实现,当执行synchronized同步块的时候jvm会根据启用的锁和当前线程的争用情况,决定如何执行同步操作。
在所有的锁都启用的情况下线程进入临界区时会先去获取偏向锁,如果已经存在偏向锁了,则会尝试获取轻量级锁,启用自旋锁,如果自旋也没有获取到锁,则使用重量级锁,没有获取到锁的线程阻塞挂起,直到持有锁的线程执行完同步块唤醒他们
偏向锁是在无锁争用的情况下使用的,也就是同步开在当前线程没有执行完之前,没有其它线程会执行该同步块,一旦有了第二个线程的争用,偏向锁就会升级为轻量级锁,如果轻量级锁自旋到达阈值后,没有获取到锁,就会升级为重量级锁。
如果线程争用激烈,那么应该禁用偏向锁。
偏向锁、轻量级锁、重量级锁的比较
重量级锁 |
轻量级锁 |
偏向锁 |
|
适用场景 |
发生了锁争抢的情况:多条线程进入同步块并争用锁 |
虽然很多线程,但是没有冲突:多条线程进入同步块,但是线程进入时间错开因而并未争抢锁 |
自始至终只有一个线程:只有一个线程进入同步块 |
本质 |
互斥同步 |
CAS操作代替互斥同步 |
取消同步操作 |
优点 |
不会空耗CPU |
不会阻塞 |
不阻塞,执行效率高(只有第一次获取偏向锁时需要CAS操作,后面只是比对ThreadId) |
缺点 |
阻塞,上下文切换,重量级操作 |
长时间获取不到锁空耗CPU |
适用场景太局限。若竞争产生,会有额外的偏向锁撤销的消耗 |
不同的锁有不同特点,每种锁只有在其特定的场景下,才会有出色的表现,java中没有哪种锁能够在所有情况下都能有出色的效率,引入这么多锁的原因就是为了应对不同的情况。
转载于:https://my.oschina.net/u/3866531/blog/2050750
【synchronized底层原理之4】锁的升级过程及比较相关推荐
- Java并发编程—Synchronized底层优化(偏向锁、轻量级锁)
原文作者:Matrix海 子 原文地址:Java并发编程:Synchronized底层优化(偏向锁.轻量级锁) 目录 一.重量级锁 二.轻量级锁 三.偏向锁 四.其他优化 五.总结 一.重量级锁 上篇 ...
- 19.Atomic系列之LongAdder的底层原理(分段锁提升并发性能)
老王:小陈啊,上一章我们讲解了cas的缺陷,无法同时更新多个变量.以及ABA的问题.以及如果使用AtomicReference解决同时更新多个变量,如果使用AtomicStampedReference ...
- Java并发编程-synchronized底层原理
synchronized底层原理与Monitor密切相关 1.Java对象头 以 32 位虚拟机为例 普通对象 对象的类型,如Student类型,Teacher类型等是由KlassWord来表示的,它 ...
- 【java】 从hotspot底层对象结构理解锁膨胀升级过程
文章目录 1.概述 2. 案例 2.1 对象分布 2.2 偏向锁 2.3 轻量级锁 2.4 重量级锁 M.扩展 1.概述 本文章是视频: 从hotspot底层对象结构理解锁膨胀升级过程 的笔记. 此文 ...
- 一篇文章带你弄懂乐观锁与悲观锁,CAS原子性,synchronized底层原理
文中加入了个人理解,如有不准确的地方欢迎提出,笔者会及时的进行改正. 乐观锁与悲观锁 乐观锁: 假设数据不会发生冲突,只有在进行数据更新的才会对数据进行检查,如果冲突则更新失败并返回错误信息 悲观锁: ...
- Java并发编程:Synchronized底层优化(偏向锁、轻量级锁)
一.重量级锁 上篇文章中向大家介绍了Synchronized的用法及其实现的原理.现在我们应该知道,Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的.但是监视器锁本质 ...
- synchronized底层原理_你用过synchronized吗?它的底层原理是什么?Java经典面试题来了...
并发编程已经成为程序员必备技能 作为Java程序员,不懂得并发编程显然已经不能满足市场需求了,尤其是在面试过程中将处于被动地位,也有可能面试将就此终结. 那么作为Java开发者的你,日常虽然可以基于J ...
- 搞定高并发,岂能不懂Synchronized底层原理?
Synchronized 是 Java 中解决并发问题的一种最常用的方法,也是最简单的一种方法.本文作者将全面剖析 Synchronized 的底层原理. Synchronized 的基本使用 Syn ...
- Synchronized的原理及自旋锁,偏向锁,轻量级锁,重量级锁的区别
在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,Java S ...
最新文章
- leetcode--买股票的最佳时机II--python
- oracle10默认备份路径,oracle 10g RMAN备份及恢复
- java代码,继承。。。主要是传值,赋值。
- 联发科mtk和骁龙730哪个好_不惧高通挑战!联发科G90芯片发布,强势干翻骁龙730...
- 前端学习(969):移动端300ms延时问题
- pom模块依赖关系梳理
- bookstore项目学到的对象
- 定积分定义求极限新花样
- HttpServletRequest获取中文参数乱码问题
- 如何用个人电脑打造量子模拟器
- JAVA-国密算法SM3和SM4应用Example
- 10G SR光模块取消ER调试可行性分析
- python爬取指定分辨率模特壁纸
- g华清远见基于linux和Qt,【华清远见】QT编程实例集
- SQL “varchar转换为numeric时出错” 的小插曲
- java_Stream流和Optional
- 性格色彩测试android程序开发之七--测试题模块dialog的实现
- springboot 自定义filter
- 项目管理_项目范围管理
- 【Python】利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456
热门文章
- AI最优论文+代码查找神器:966个ML任务、8500+论文任你选
- Shell命令-搜索文件或目录之whereis、locate
- 理解大型分布式网站你应该知道这些概念
- 20165303实验一 Java开发环境的熟悉
- 利用ssh+rsync+inotify实现数据的异地实时同步
- 数据显示Windows Phone市场份额依旧十分稳定
- 浅谈Jquery中的bind()、live()、delegate()、on()绑定事件方式
- CentOS 6.3编译安装Nginx1.2.2+MySQL5.5.25a+PHP5.4.5
- ios6.x越狱将不会再呈现了
- One Day-XML:XSLT