synchronized锁升级过程(偏向锁,轻量级锁和重量级锁)
前言
本文没有什么高大上的理念,旨在帮助读者更好的理解synchronized锁升级过程,尤其是其中偏向锁,轻量级锁和重量级锁的作用(全程通俗易懂,简洁明了,如有错误的地方,欢迎指出)
一、synchronized锁升级过程
synchronized锁升级过程可以分成四步走:
- 没有线程抢锁(syn无锁状态)
- 有且只有一个线程抢锁,即对锁做出了标记(syn为偏向锁)
- 多个线程抢锁,但只有第一个对锁做出标记的线程可以享用锁,其他的线程需通过消耗cpu自旋(可以理解做while循环,但循环体没有内容)来避免被阻塞。(自旋拿到锁后,syn为轻量级锁)
- 但自旋到一定时间或者次数如果其他线程还没有拿到锁,则锁进化(syn为重量级锁)
二、区分偏向锁,轻量级锁和重量级锁的作用
偏向锁和轻量级锁相对于重量级锁主要有两个好处:
-
减少线程竞争带来的开销:偏向锁和轻量级锁的设计目标是降低线程竞争所带来的额外开销(线程的阻塞和唤醒总是要操作系统的介入,需要在用户态和内核态之间转换来实现的)。轻量级锁利用乐观的技术(比如CAS,即比较并交换)在竞争较低的情况下尽量避免立即采用操作系统级别的机制(即避免线程阻塞,唤醒)。
-
避免操作系统级别的Mutex Lock开销:使用偏向锁和轻量级锁有助于尽量避免立即使用重量级的操作系统级Mutex Lock。在偏向锁和轻量级锁的情况下,如果一个线程一直持有锁,就无需牵涉到操作系统。
也就是说偏向锁和轻量级锁其实并没有真正的用到锁,只是相当于对锁对象做了一个标记,表明有线程正在使用锁对象。而要真正的用到锁的互斥功能,则是重量级锁来实现的。
总结
偏向锁和轻量级锁的作用一是为了避免线程切换引起的额外系统开销(通过自旋),二是为了避免使用操作系统的Mutex Lock引起的额外系统开销(通过对锁对象做标记)。而重量级锁就是因为有这两种系统开销,才叫重量级锁。