CPU|java面试——常见的锁和锁升级( 五 )
应用程序线程可以被安全地停止掉的那个时间点 , 就叫做安全点 。 这一术语也通常用来指代SWT暂停 。
查看安全点日志:
要查看安全点停顿 , 可以打开安全点日志 , 通过设置JVM参数 -XX:+PrintGCApplicationStoppedTime 会打出系统停止的时间 , 添加-XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1 这两个参数会打印出详细信息 , 可以查看到使用偏向锁导致的停顿 , 时间非常短暂 , 但是争用严重的情况下 , 停顿次数也会非常多;
注意:安全点日志不能一直打开:
如果在生产系统上要打开 , 再再增加下面四个参数: -XX:+UnlockDiagnosticVMOptions -XX: -DisplayVMOutput -XX:+LogVMOutput -XX:LogFile=/dev/shm/vm.log
JVM开启和关闭安全点:
- 开启偏向锁:-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0
- 关闭偏向锁:-XX:-UseBiasedLocking
偏向锁的释放只有遇到锁竞争的时候 , 持有偏向锁的线程才会释放锁 , 否则线程不会主动去释放偏向锁 。 偏向锁的撤销时需要等待全局安全点(在这个时间点上没有字节码正在执行) , 它会首先暂停拥有偏向锁的线程 , 判断锁对象是否处于被锁定状态 , 撤销偏向锁后恢复到未锁定(标志位为“01”)或轻量级锁(标志位为“00”)的状态
偏向锁如何升级为轻量级锁(00)?当偏向锁发生锁竞争的时候 , 偏向锁释放 , 然后相互竞争的线程在自己的线程栈内就会生成Lock Record 锁记录 , 然后每个线程之间通过自旋的方式竞争把这个锁记录写到mark Word里面 , 哪个线程最先修改成功, 谁就获取到这把锁 , 这就是轻量级锁 , 也叫自旋锁 。
解释下为什么需要把轻量级锁升级到重量级锁?轻量级锁是处于用户态的 , 不需要向内核申请 , 所以比较快 , 但是重量级锁是放在内核态的 ,
因为自旋锁是很消耗cpu的 , 如果获取到锁的那个线程一直在执行 , 不释放 , 这时候锁是需要升级的 ,
升级成重量级锁的好处是什么?
所以 , 关键就是重量级锁的队列里面 , 可以是wait状态 , 阻塞的 , 不消耗cpu资源 , 什么时候可以执行了 , 再唤醒
轻量锁如何升级成为重量级锁(10)?竞争进一步加剧:自旋超过10次:-XXPreBlockSpin , 或者cpu核数的一半jdk1.6之后有了自旋自适应 , jdk自己会控制
面试回答锁升级的过程?
- new对象 , 此时默认是加了偏向锁 , 第一个访问该对象的线程会把当前线程id放到这个对象的mark word的对象头里面作为一个标记
- 出现线程竞争 , 则通过CAS操作竞争锁 , 如果竞争成功 , 则将Mark Word中线程ID设置为当前线程ID , 继续执行代码 , 竞争失败 , jvm让拥有偏向锁的线程挂起 , 等到了安全点的时候stw , 释放锁 , 锁升级为轻量级锁 , 锁标志位变为00 , 每个线程之间通过自旋的方式吧自己线程栈里面的lock record写入到mark word , 谁修改成功谁就获取到锁——自旋锁 。
- Java基础知识回顾,还记得吗?
- mybatis sharding-jdbc Java8日期
- 树莓派控制步进电机-TB6600-Java版本
- 德州点创教育JavaScript正则表达式授课大纲
- 如何编写JAVA小白第一个程序
- 英特尔推出新款四核CPU,目标直指Ryzen3 3300X
- 入门到老手全覆盖,锐龙CPU给3D创作加速
- java安全编码指南之:异常简介
- Java学习路线图
- Java核心技术点有哪些 有没有什么书籍推荐