JVM内部细节之二:偏向锁(Biased Locking)
在前面一片文章《JVM内部细节之一:synchronized关键字及实现细节》中已经提到过偏向锁的概念,在理解什么是偏向锁前必须先理解什么是轻量级锁(Lightweight Locking)。引入偏向锁是为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径,因为轻量级锁的获取及释放依赖多次CAS原子指令,而偏向锁只需要在置换ThreadID的时候依赖一次CAS原子指令(由于一旦出现多线程竞争的情况就必须撤销偏向锁,所以偏向锁的撤销操作的性能损耗必须小于节省下来的CAS原子指令的性能消耗)。下面看具体细节:
一、对象头中的Mark Word布局

在上一篇文章中所讨论的轻量级锁中在我参考的Paper中对于重量级锁的实现并没有通过状态位来表现而是直接通过在轻量级锁的Monitor Record中关联一个底层操作系统的互斥信号量来实现重量级锁的操作(并不影响我们理解JVM内部锁的运作过程),在偏向锁的处理过程中并不涉及重量级锁,我们这里只需要关心biasable和lightweight locked两种状态。在JDK1.6以后默认已经开启了偏向锁这个优化,我们可以通过在启动JVM的时候加上-XX:-UseBiasedLocking参数来禁用偏向锁(在存在大量锁对象的创建并高度并发的环境下禁用偏向锁能够带来一定的性能优化)。
二、偏向锁的获取过程(假设开启了偏向锁优化):
(1)初始时对象处于biasable状态,并且ThreadID为0即biasable & unbiased状态(这里不讨论epoch和age)
(2)当一个线程试图锁住一个处于biasable & unbiased状态的对象时,通过一个CAS将自己的ThreadID放置到Mark Word中相应的位置,如果CAS操作成功进入第(3)步否则进入(4)步
(3)当进入到这一步时代表当前没有锁竞争,Object继续保持biasable状态,但是这时ThreadID字段被设置成了偏向锁所有者的ID,然后进入到第(6)步
(4)当前线程执行CAS获取偏向锁失败(这一步是偏向锁的关键),表示在该锁对象上存在竞争并且这个时候另外一个线程获得偏向锁所有权。当到达全局安全点(safepoint)时获得偏向锁的线程被挂起,并从偏向锁所有者的私有Monitor Record列表中获取一个空闲的记录,并将Object设置为LightWeight Lock状态并且Mark Word中的LockRecord指向刚才持有偏向锁线程的Monitor record,最后被阻塞在安全点的线程被释放,进入到轻量级锁的执行路径中,同时被撤销偏向锁的线程继续往下执行同步代码。
(5)当一个线程试图锁住一个处于biasable & biased并且ThreadID不等于自己的ID时,这时由于存在锁竞争必须进入到第(4)步来撤销偏向锁。
(6)运行同步代码块
二、偏向锁的解锁过程:
(1)偏向锁解锁过程很简单,只需要测试下是否Object上的偏向锁模式是否还存在,如果存在则解锁成功不需要任何其他额外的操作。
三、参考资料:
JVM内部细节之二:偏向锁(Biased Locking)的更多相关文章
- JVM 内部原理(二)— 基本概念之字节码
JVM 内部原理(二)- 基本概念之字节码 介绍 版本:Java SE 7 每位使用 Java 的程序员都知道 Java 字节码在 Java 运行时(JRE - Java Runtime Enviro ...
- JVM内部细节之一:synchronized关键字及实现细节(轻量级锁Lightweight Locking)
在C程序代码中我们可以利用操作系统提供的互斥锁来实现同步块的互斥访问及线程的阻塞及唤醒等工作.然而在Java中除了提供Lock API外还在语法层面上提供了synchronized关键字来实现互斥同步 ...
- JVM内部细节之三:字符串及字符串常量池
本人最近正在面试,然后注意到总是有公司喜欢考String的问题,如字符串连接有几种方式,它们之间有什么不同等问题:要不就是给一段代码问创建了几个对象.那么该不该问呢?我认为当面试有一定工作经验的求职者 ...
- 内部锁之一:锁介绍(偏向锁 & 轻量级锁 & 重量级锁 & 各自优缺点及场景)
一.内部锁介绍 上篇文章<Synchronized之二:synchronized的实现原理>中向大家介绍了Synchronized原理及优化锁.现在我们应该知道,Synchronized是 ...
- Java偏向锁实现原理(Biased Locking)
http://kenwublog.com/theory-of-java-biased-locking 阅读本文的读者,需要对Java轻量级锁有一定的了解,知道lock record, mark wor ...
- java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁(转载)
之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比>,当时对这个测试结果很疑惑,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高 ...
- java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁
之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比>,当时对这个测试结果很疑惑,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高 ...
- Java锁---偏向锁、轻量级锁、自旋锁、重量级锁
之前做过一个测试,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高(当时感觉它的效率应该是最差才对): 2. AtomicInteger效率最不稳定,不同并发情况下表 ...
- java多线程之锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁
转载至:https://blog.csdn.net/zqz_zqz/article/details/70233767 之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比 ...
随机推荐
- Linux:查看进程运行时间
查看进程运行时间 应用ps命令,加选项-Ao,加参数,最后过滤. ps -Ao pid,tty,user,stime,etime,comm,args| grep firefox pid:进程ID tt ...
- Linux:at命令详解
at命令 at命令为单一工作调度命令.at命令非常简单,但是在指定时间上却非常强大 语法 at [选项] time at > 执行的命令 ctrl+d 选项 -m :当指定的任务被完成之后,将给 ...
- python synflood test
#!/usr/bin/env python ######################################### # # SYNflood - A multithreaded SYN F ...
- ES6.0 Generator 三种用法
// Generator start ------- thunk 用法 const Thunk = function(fn) { return function (...args) { return ...
- HAL_RTC_MspInit Msp指代什么?
/********************************************************************************* * HAL_RTC_MspInit ...
- CentOS使用安装光盘建立本地软件源
本实验的目的是使用CentOS的两张DVD安装光盘作为本地软件源,避免执行yum安装命令时每次都要从网络重新下载. 安装createrepo软件包 createrepo是制作软件源所需要的一个工具,默 ...
- CodeForces - 1093G:Multidimensional Queries (线段树求K维最远点距离)
题意:给定N个K维的点,Q次操作,或者修改点的坐标:或者问[L,R]这些点中最远的点. 思路:因为最后一定可以表示维+/-(x1-x2)+/-(y1-y2)+/-(z1-z2)..... 所以我们可以 ...
- 2018-2019-2 《网络对抗技术》Kali安装 Week1 20165212
2018-2019-2 <网络对抗技术>Kali安装 Week1 20165212 1.完成安装linux kali和vm tools 装的第三遍成功安装.前面两次镜像文件不行,没驱动(网 ...
- hdu1160 dp
hdu1160 题意:给出很多老鼠的数据,分别是它们的体重和跑速,为了证明老鼠越重跑得越慢,要找一组数据,由若干个老鼠组成,保证老鼠的体重依次增加而跑速依次减小,问这组数据最多能有多少老鼠,并按体重从 ...
- k8s dockerk个人学习(1)
虚拟机部署k8s 1. 创建虚拟机 虚拟机用的是virtualBox和vagrant工具,百度安装virtualBox和vagrant 创建vagrant目录并创建文件Vagrantfile内容为 V ...