ReentrantLock (5) —— 非公平锁总结

经过对 ReentrantLock 中非公平锁源码的解读,可以总结一下其中的一些核心点。

1、什么是锁?什么是加锁?什么是解锁?什么是重入?

锁可以理解为:AQS 中 state 属性从0更新为1这个过程。
重入可以理解为:成功将 state 属性从0更新为1的这条线程,又将state从1进行了多次累加的过程。
加锁可以理解为:某个线程通过CAS成功的将 state 属性从0更新为1。

解锁与加锁是相对的
解锁可以理解为:将 AQS 中 state 属性从1更新为0的过程。

PS:此处只是简单描述核心关键原理

2、自旋指的是什么?

以我的理解,一个线程获取不到锁,并不会无限的自旋。真正自旋的地方是加锁过程的两个 for 循环。

  1. 第一个 for 循环是为了保证让线程安全的加入到队列尾部
  2. 第二个 for 循环是为了让线程正确的更新前驱节点状态,然后进入阻塞状态。等待被唤醒的时候,再去夺取锁。获取不到,就继续刚刚的过程

3、非公平锁的加锁流程:

ReentrantLock (5) —— 非公平锁总结_第1张图片
非公平锁的加锁流程
  1. 线程通过 CAS 先去获取锁,如果成功,则结束。
  2. 如果获取锁失败,则进入公共获取锁的流程,如果成功,则结束。
  3. 如果获取锁失败,则将当前线程封装到 Node 中,加入队列尾部
  4. 更新自己前驱节点的状态,并尝试获取锁,如果成功则结束。
  5. 如果失败,则阻塞当前线程,等待被唤醒

4、非公平锁的解锁流程:

ReentrantLock (5) —— 非公平锁总结_第2张图片
非公平锁的解锁流程

5、非公平锁的非公平原理

非公平锁的申请锁过程看似是先进先出有序的,它的非公平之处在于:在头结点马上解锁做交接的时候,其他线程可以马上通过 CAS 进行抢夺,而且不需要加入队列。如果抢夺成功,那等待交接的后继节点只能认栽,继续在后面等着。只要排了队的节点,就一定要按照队列顺序去获取锁。没有排队的可以直接插队获取锁。

本分排队的,有可能无法公平的获取到锁;反而在最前面插队的,能更快的获取到锁。

以上都是个人愚见,如有理解不对的地方还望指出,大家一起交流,一起进步。

你可能感兴趣的:(ReentrantLock (5) —— 非公平锁总结)