描述一下锁的四种状态及升级过程?
1、锁的四种状态
无锁、偏向锁、轻量级锁、重量级锁
以下为32位对象头描述
以下为64位对象头描述
当线程访问同步代码块时,首先判断当前锁状态是否为可偏向状态(对象头中偏向锁=1,锁标志=01)在JDK1.6以上默认开启,开启后程序启动几秒后才会被激活
如果是可偏向状态,检查MarkWord存储的是否是当前线程ID
- 是,获得偏向锁,执行同步代码块
- 不是,CAS操作竞争锁,替换线程ID
- 替换成功,MarkWord的线程ID设置为当前线程ID(线程复用),执行同步代码块
- 替换失败,锁撤销,升级为轻量级锁
同一类对象多次撤销升级达到阈值20,则偏向锁认为,后面的锁需要重新偏向新的线程(批量重偏向)
如果阈值达到40次,则偏向锁认为偏向锁撤销过于频繁,后面直接使用轻量级锁
升级为轻量级锁的情况
- 如果不是可偏向状态,直接升级为轻量级锁
- 偏向锁撤销次数过多
加锁时,会在当前线程栈帧中划出一块空间,作为该锁记录,并且将锁对象MarkWord复制到该锁记录中,CAS操作将MarkWord更新为该锁记录的指针,锁记录中的owner指针指向对象头的MarkWord。
- 更新成功,MarkWord锁标志位为00,表示轻量级锁状态
- 更新失败,检查锁对象MarkWord是否指向当前线程栈帧中的锁记录
- 是,表示锁重入,在当前线程栈帧中锁记录+1
- 否,自旋等待(默认10次),等待次数达到阈值,升级为重量级锁
升级为重量级锁的情况
- 竞争加剧,CAS自旋到一定次数升级为重量级锁
- 自旋线程数超过CPU核数的一半, 1.6之后,加入自适应自旋Adapative Self Spinning,JVM自己控制
获取锁成功,进入EntryList(获取锁的缓冲区、入口)
- 在调用wait方法后,会进入等待唤醒队列(WaitSet)等待
- 在调用notify方法后,则可能进入EntryList
获取锁失败,进入一个等待拿锁队列(cxq)等待
具体重量级锁加锁过程:
1、分配⼀个ObjectMonitor对象,把MarkWord锁标志置为‘10’,然后MarkWord存储指向ObjectMonitor对象的指针。ObjectMonitor对象有两个队列和⼀个指针,每个需要获取锁的线程都包装成ObjectWaiter对象
2、多个线程同时执行同⼀段同步代码时,ObjectWaiter先进⼊EntryList队列,当某个线程获取到对象的monitor以后进⼊Owner区域,并把monitor中的owner变量设置为当前线程,同时monitor中的计数器count+1
说明:
monitor:每个Java对象都有一把锁,称为内部锁或monitor锁
owner,指向的是当前获得线程的地址,用来判断当前锁是被哪个线程持有
用户态:偏向锁、轻量级锁
内核态:重量级锁
首先来了解下synchronized重量级锁实现原理?
通过对象内部的一个叫做监视器锁(monitor)来实现的,监视器锁本质又是依赖于底层的操作系统的 Mutex Lock(互斥锁)来实现的。而操作系统实现线程之间的切换需要从用户态转换到核心态,这个成本非常高。
在JDK6以前,只有重量级锁,阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态切换需要耗费处理器时间。
在JDK6中,为了提高性能,引入了偏向锁和轻量级锁。
大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了减少线程获得锁的代价,所以引入了偏向锁
自旋锁消耗CPU资源,重量级锁有等待队列,不会消耗CPU资源
不一定,在多线程竞争情况下,偏向锁会涉及锁撤销,这时候应该直接使用自旋锁
重入次数必须记录,才能知道要解锁几次
- 轻量级锁,记录在线程栈,每插入一次,LockRecord+1
- 重量级锁,记录在ObjectMonitor字段上
不是的,Hopspot对象头主要包括两部分数据:MarkWord(标记字段) 和 classPointer(类指针)
不行的,是一个不可逆的过程,主要是为了提高获得锁和释放锁的效率
偏向锁:适用于一个线程,不会有锁消耗,锁撤销
轻量级锁:适用于多个线程竞争,但同步代码块执行快的情况下,因为自旋会消耗CPU
重量级锁:适用于多个线程竞争,但同步代码块执行慢的情况下,不消耗CPU,可以提高吞吐量
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击