自旋锁,偏向锁,轻量级锁 和 重量级锁
自旋锁
如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,只需让线程执行一个忙循环(自旋),等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程和内核的切换的消耗。
自旋等待不能代替阻塞,自旋等待本身虽然避免了线程切换的开销,但是要占用处理器时间,因此如果锁被占用时间很短,自旋等待效果就会非常好,但如果锁被占用的时间很长,那么自旋的线程只会白白消耗处理器资源,不会有任何有用的工作,反而会带来性能上的浪费。
偏向锁
在没有实际竞争的情况下,还能够针对部分场景继续优化。如果不仅仅没有实际竞争,自始至终使用锁的线程都只有一个,那么维护轻量级锁都是浪费的。偏向锁的目标是,减少无竞争且只有一个线程使用锁的情况下,使用轻量级锁产生的性能消耗。轻量级锁每次申请、释放锁都至少需要一次CAS,但偏向锁只有初始化时需要执行一次CAS。偏向锁假定将来只有第一个申请锁的线程会使用锁(不会有任何线程再来申请锁),因此只需要在Mark Word中CAS记录owner(线程ID),记录成功则偏向锁获取成功,记录锁状态为偏向锁,以后当前线程等于owner就可以零成本地直接获得锁;否则说明有其他线程竞争,膨胀为轻量级锁。
特点:只有等到线程竞争出现才释放偏向锁,持有偏向锁的线程不会主动释放偏向锁。之后的线程竞争偏向锁,会先检查持有偏向锁的线程是否存活,如果不存活,则对象变为无锁状态,重新偏向;如果仍存活,则偏向锁升级为轻量级锁,此时轻量级锁由原持有偏向锁的线程持有,继续执行其同步代码,而正在竞争的线程会进入自旋等待获得该轻量级锁。
轻量级锁
轻量级锁的目标就是减少无实际竞争情况下,使用重量级锁产生的性能消耗,包括系统调用引起的内核态与用户态切换、线程阻塞造成的线程切换等。轻量级锁是相对于重量级锁而言的。使用轻量级锁时,不需要申请互斥量,仅仅将Mark Word中的部分字节CAS更新指向线程栈中的Lock Record,如果更新成功,则轻量级锁获取成功,记录锁状态为轻量级锁;否则,说明已经有线程获得了轻量级锁,目前发生了锁竞争(不适合继续使用轻量级锁),接下来膨胀为重量级锁。
重量级锁
底层通过操作系统的mutex lock实现。等待锁的线程会被阻塞,由于Linux下Java线程与操作系统内核态线程一一映射,所以涉及到用户态和内核态的切换、操作系统内核态中的线程的阻塞和恢复。这种方式的成本非常高,因此后来称这种锁为“重量级锁”。synchronized就属于这种锁。
用户态 和 内核态 ???
synchronized关键字并非一开始就该对象加上重量级锁,也是从偏向锁,轻量级锁,再到重量级锁的过程。这个过程也告诉我们,假如我们一开始就知道某个同步代码块的竞争很激烈、很慢的话,那么我们一开始就应该使用重量级锁了,从而省掉一些锁转换的开销。
互斥锁(重量级锁)也称为阻塞同步、悲观锁
重量级锁是依赖对象内部的monitor锁来实现的,而monitor又依赖操作系统的MutexLock(互斥锁)来实现的,所以重量级锁也称为互斥锁
为什么重量级线程开销很大的?
当系统检查到锁是重量级锁之后,会把等待想要获得锁的线程进行阻塞,被阻塞的线程不会消耗cpu。但是阻塞或者唤醒一个线程时,都需要操作系统来帮忙,这就需要从用户态转换到内核态,而转换状态是需要消耗很多时间的,有可能比用户执行代码的时间还要长。
参考文档:https://blog.csdn.net/qq_36071795/article/details/83818331
,https://blog.csdn.net/laravelshao/article/details/80316003
转载于:https://www.cnblogs.com/william-dai/p/10895998.html
自旋锁,偏向锁,轻量级锁 和 重量级锁相关推荐
- java 锁降级 知乎_HotSpot VM重量级锁降级机制的实现原理
HotSpot VM内置锁的同步机制简述: HotSpot VM采用三中不同的方式实现了对象监视器--Object Monitor,并且可以在这三种实现方式中自动切换.偏向锁通过在Java对象的对象头 ...
- (JUC)图文并茂!!!! 超详细 偏向锁VS轻量级锁VS重量级锁VS自旋
偏向锁,轻量级锁,重量级锁 前言 java对象内存布局 (1)重量级锁(Moniter) (2)轻量级锁 锁膨胀.自旋.自适应自旋 (3)偏向锁(以64位虚拟机为例) 2.偏向锁撤销的3种情况 (1) ...
- Synchronized的原理及自旋锁,偏向锁,轻量级锁,重量级锁的区别
在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,Java S ...
- 1.6的锁优化(适应性自旋/锁粗化/锁削除/轻量级锁/偏向锁)
高效并发是JDK 1.6的一个重要主题,HotSpot虚拟机开发团队在这个版本上花费了大量的精力去实现各种锁优化技术,如适应性自旋(Adaptive Spinning).锁削除(Lock Elimin ...
- Java如何避免重量级锁,Java 中锁是如何一步步膨胀的(偏向锁、轻量级锁、重量级锁)...
文章目录 重量级锁(Mutex Lock) 偏向锁(比较 ThreadID) 偏向锁获取过程 偏向锁的释放 轻量级锁(自旋) 轻量级锁的加锁过程 轻量级锁的释放 总结 重量级锁(Mutex Lock) ...
- 2021-06-01 深入分析偏向锁、轻量级锁和重量级锁
目录 一 重量级锁 1.1 什么是重量级锁?重量级是怎么体现的? 1.2 重量级锁的监视器工作流程 1.2.1 线程竞争锁 1.2.2 线程锁竞争成功 1.2.3 线程竞争锁失败 1.2.4 运行中的 ...
- JVM内部锁升级过程(偏向锁,轻量级锁,重量级锁)
目录 对象在内存中是如何布局的 如何查看对象在内存中的布局 markword数据结构 加锁后发生了什么 偏向锁 什么是偏向锁 偏向锁定时hashCode 哪去了? 为什么需要偏向锁 为什么从JDK15 ...
- 并发——锁升级(偏向锁,轻量级锁,重量级锁,及常见锁)
锁升级 原因:为了减少获得锁和释放锁带来的性能消耗,所以有了升级锁 流程: 无锁状态-偏向锁(jvm配置是否开启)----轻量级锁----重量级锁(不可逆,只要成为重量级,释放锁就一直是重量级) 常见 ...
- 十二、偏向锁、轻量级锁、重量级锁,锁的膨胀过程
1.对象的状态有几种: 无锁.偏向锁.轻量级锁.重量级锁.GC标记,共5个状态 2.锁的膨胀过程 无锁:程序多线程执行过程中没有去执行synchronized修饰区域或者方法. 偏向锁:发生在程序单线 ...
- 偏向锁、轻量级锁、重量级锁的区别和解析
为了换取性能,JVM在内置锁上做了非常多的优化,膨胀式的锁分配策略就是其一.理解偏向锁.轻量级锁.重量级锁的要解决的基本问题,几种锁的分配和膨胀过程,有助于编写并优化基于锁的并发程序. 内置锁的分配和 ...
最新文章
- SBIO | 西农韦革宏组-大豆土壤细菌门间负向互作影响群落的动态变化和功能
- php文件放到html中,怎么把HTML作为模板放到PHP中
- BGP路由协议特性和三张表
- Windows远程桌面管理--功能强大的远程批量管理工具
- SCCM 2012 SP1系列(十六)资产管理和远程管理
- 卢伟冰:小米Civi女性购买用户占比超60%
- python四分位数_分位函数(四分位数)概念与pandas中的quantile函数
- 【网络安全工程师面试合集】— 渗透资源 操作系统大合集
- 的标题形状工具在哪里_一分钟教你做一款让人眼前一亮的标题!你想学吗?「Word技巧」...
- linux shell 之 grep
- (CVPR_2021) Center-based 3D Object Detection and Tracking
- 防止屏蔽,背投广告代码的完善
- 流畅的python mobi_流畅的Python中文pdf_Python教程
- python 拼音输入法_用Python从头开始实现一个中文拼音输入法?
- opencv如何隐藏窗口-cvNameWindow创建窗口的时候会创建两个窗口,一个主窗口,一个子窗口。
- ESXI主机密码忘记恢复
- mysql中exec语句_SQL语句-exec执行
- android 录屏功能,Android开发如何实现录屏小功能
- Android Mars XLog的编译
- css 网站大背景(按比例缩放背景图片)