摘要

AbstractQueuedSynchronizer是一个线程同步的管理器,以下简称AQS。在juc包下面,大多数同步工具类都是基于AQS来实现多线程之间的同步。但它是如何做到让线程获取/释放锁,来达到获得资源的使用权的呐?简单的说,就是在AQS中有一个状态值(private volatile int state;),当某一线程需要获取/释放锁的时候,就去查看/更改这个状态值。跟具这个值来判定是否能获得资源,否则就进入由AQS管理的CLH队列中(由AbstractQueuedSynchronizer的内部类Node来实现)。在以下我总说的[获取锁]就是去检查这个状态值,请自行脑补。

阅读完本文,你能了解到什么

  • 公平锁和非公平锁的实现区别
  • CAS的原理
  • 如何获取和释放锁

内容

为了搞懂AQS的原理,我这里用一个比较常用的AQS的子类来进一步说明,ReentrantLock(重入锁)。ReentrantLock中持有引用Sync,Sync就是对AQS的继承,大家看下源代码就一目了然了。在使用ReentrantLock时,我们可以有选择性的创建公平锁和非公平锁。跟具创建实例时,传递的boolean型参数,如下构造方法;

我们先分析公平锁,然后非公平锁就比较简单了

  • [公平锁]
    顾名思义,多个线程公平的获取到锁。举个例子,直白点说。比如说有5个线程想要获取锁,但是锁只能被1个线程获得,那么剩下的4个线程就被放置到CLH队列中,也就是在Node节点的链表中;当这个线程释放锁的时候,会让这个队列中,位于头节点的这个线程(如果这个头结点的线程已经被取消了那么就取下一个)获取到锁,以此类推,从而达到公平的获取到锁。

1 获取锁,调用lock方法,它会去调用父类AQS中的acquire方法。

1.1 我们接着来看下acquire方法

1.1.1 接着看tryAcquire方法,子类中分别对应公平和非公平锁获取(这里先看公平锁获取到实现)

2 收藏


直接登录

推荐关注