在轻量级锁的时候,都是使用自旋CAS来尝试获取锁,如果存在竞争自旋获取失败,那么就会膨胀升级为重量级锁,此时会通过monitor监视器来实现锁,大概流程如下:
- 通过CAS尝试把monitor的owner字段设置为当前线程。
- 如果设置之前的owner指向当前线程,说明当前线程再次进入monitor,即重入锁,执行recursions ++ ,记录重入的次数。
- 如果当前线程是第一次进入该monitor,设置recursions为1,_owner为当前线程,该线程成功获得锁并返回。
- 如果获取锁失败,则等待锁的释放。
而等待就需要调用park()方法然后线程被挂起阻塞,竞争到锁的线程会unpark()唤醒。这两个操作都是调用底层操作系统的Mutex互斥原语,会存在操作系统用户态和内核态的转换,这种切换会消耗大量的系统资源。所以synchronized是Java语言中是一个重量级(Heavyweight)的操作。
注:轻量级锁的时候只会自旋CAS不会阻塞!
参考:https://blog.csdn.net/weixin_39809175/article/details/110498982