Sychronized的偏向锁、轻量级锁、重量级锁
-
Synchronized很多人都会称呼它为重量级锁
-
但是随着JDK 6对Synchronized进行了各种优化之后,有些情况下它并不那么重了
-
JDK 6中为了减少获得锁和释放锁带来的性能消耗而引入的
偏向锁和轻量级锁
- 简单说就是,线程创建都是操作系统才能完成的
阻塞和唤醒这两个步骤也都是需要操作系统去进行
,很消耗资源- 偏向锁和轻量级锁就不再有
阻塞和唤醒
的步骤了,不使用操作系统 - 程序自己完成,就有了偏向锁和轻量级锁
偏向锁:在锁对象的
对象头
中记录⼀下当前获取到该锁的线程ID
,该线程下次如果⼜来获取该锁就可以直接获取到了
- 偏向锁是只有一个线程操作锁的时候,一旦有竞争就会升级到轻量锁
轻量级锁:由
偏向锁升级
⽽来,当⼀个线程获取到锁后,此时这把锁是偏向锁,此时如果有第⼆个线程来竞争锁,偏向锁就会升级为轻量级锁
- 轻量级锁底层是通过
⾃旋
来实现的,并不会阻塞线程- 一个线程在持有锁,一个在自旋
- 这里都是使用CAS机制来竞争锁的,不会跑到操作系统层面
- 若当前
只有一个等待线程
,则该线程通过自旋进行等待。 - 但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁升级为重量级锁。
重量级锁: 如果⾃旋次数过多仍然没有获取到锁,则会升级为重量级锁,重量级锁会导致线程阻塞
- 重量级锁就说明获取锁的线程太多了,需要把其他线程阻塞了
- 凡是到了阻塞这一步了,都是重量锁了
- 阻塞和唤醒这两个步骤都是需要操作系统去进行的,
⽐较消耗时间的
- 所以叫重量级锁
⾃旋锁:⾃旋锁就是线程在获取锁的过程中,
不会去阻塞线程
,也就⽆所谓唤醒线程
- ⾃旋锁是线程通过
CAS获取预期的⼀个标记
,预计当前执行的线程为null,将自旋的线程替换进去- 如果没有获取到,则继续循环获取
- 如果获取到了则表示获取到了锁
- 这个过程线程
⼀直在运⾏中
,相对⽽⾔没有使⽤太多的操作系统资源
,⽐较轻量。
偏向锁丶轻量级锁丶⾃旋锁,都属于乐观锁,都使用了CAS技术