synchronized底层原理
synchronized关键字编译后会在同步块前后分别形成monitorenter和monitorexit两个字节码指令。
编译前
public class ThreadCommon{
public void run(){
synchronized (this){
System.out.println("hello");
}
}
}
编译后
每个Java对象都有一个对象头,而对象头里面有一个指针,指向一个monitor对象,monitor可以理解为对象监视器,monitor对象由C++实现,底层依赖的是操作系统的互斥量(mutex)。
执行monitorenter指令时,首先尝试获取锁,如果这个对象没有被锁定,则当前线程将持有锁,monitor计数器会加1,否则当前线程阻塞。
执行monitorexit指令时,monitor计数器会减1,如果减为0则代表锁被释放。
锁是一个重量级的操作,因为线程的阻塞或唤醒都是由操作系统来控制的,无法人为干预,而由操作系统来控制就不可避免陷入到用户态和内核态的转换当中,甚至转换时间大于用户代码的执行时间(比如a++这种简单的代码),下面就来介绍synchronized的锁优化机制。
锁优化
先来看看有哪些锁优化的技术:
-
自适应自旋锁
-
锁消除
-
锁粗化
-
轻量级锁
-
偏向锁
下面一一讲解。
自旋
普通自旋:
-
循环获取锁,虽然不会导致当前线程阻塞,但是会一直消耗处理器资源。
固定次数的自旋锁:
-
比如固定10次,10次自旋后仍没有获取到锁就会放弃;
自适应自旋锁:
-
自旋次数不固定,而由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定的;
锁消除
锁消除是指虚拟机即时编译器在运行时,对一些代码要求同步,但是对被检测到不可能存在共享数据竞争的锁进行消除。锁消除的主要判定依据来源于逃逸分析的数据支持,如果判断到一段代码中,在堆上的所有数据都不会逃逸出去被其他线程访问到,那就可以把它们当作栈上数据对待,认为它们是线程私有的,同步加锁自然就无须再进行。
锁粗化
如果有一连串的操作(比如循环),每个子操作用synchronized同步块包围,那么这一连串操作实际上一直在加锁->释放锁->…->加锁->释放锁,频繁的加锁释放锁会影响性能,此时虚拟机就会做出锁粗化的优化,直接对这一连串的操作整体加锁,而子操作则不加锁。
轻量级锁
在讲轻量级锁之前,有必要回顾一下对象的内存布局之对象头之Mark Word部分的存储内容,HotSpot虚拟机对象三部曲
不同锁状态下的Mark Word如下图所示。
在 HotSpot虚拟机对象三部曲 这篇文章中,我已经介绍了未锁定和轻量级锁加锁的情况,下面对轻量级锁进行一些补充。
轻量级锁解锁过程:
-
轻量级锁通过CAS解锁,如果对象的Mark Word仍然指向当前线程的锁记录,那就用CAS将对象的Mark Word与线程中的Displaced Mark Word相互替换;
-
如果替换成功,则解锁成功;
-
如果替换失败,则说明有其他线程尝试获取该锁,需要在释放锁的同时,唤醒被挂起的线程;
锁膨胀:
-
如果出现两条及以上的线程争用同一个锁的情况,那轻量级锁就不再有效,必须要膨胀为重量级锁,此时Mark Word存储指向重量级锁(monitor对象,互斥量)的指针,后面等待锁的线程也必须进入阻塞状态;
轻量级锁能提升程序同步性能是因为对于绝大部分的锁,在整个同步周期内都不存在竞争。如果没有竞争,轻量级锁通过CAS避免了使用互斥量的开销;但如果确实存在锁竞争,除了互斥量的本身开销外,还额外发生了CAS的开销。因此在有竞争的情况下,轻量级锁反而会比传统的重量级锁更慢。
偏向锁
偏是偏心的意思,表示这个锁会偏向于第一个获得它的线程,如果该锁一直没有被其他的线程获取,则持有偏向锁的线程将永远不需要再进行同步。
轻量级锁是在无竞争的情况下用CAS去消除同步使用的互斥量,而偏向锁则是在无竞争的情况下直接消除整个同步,连CAS也不做了。
偏向过程:
-
假设虚拟机启用了偏向锁,当锁对象第一次被线程获取的时候,则进入偏向模式,同时使用CAS将持有偏向锁的线程ID记录在对象的Mark Word之中;
-
如果CAS操作成功,持有偏向锁的线程以后每次进入这个锁相关的同步块时,虚拟机都可以不再进行任何同步操作(例如加锁、解锁及对Mark Word的更新操作等);
-
一旦出现另外一个线程去尝试获取这个锁的情况,则偏向模式结束,并且进入锁定状态(持有偏向锁的线程未进入同步块)或轻量级锁定状态(持有偏向锁的线程已进入同步块);
原文始发于微信公众号(初心JAVA):并发第三弹 synchronized锁优化详解
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/35551.html