1. AQS使用一个int成员变量来表示同步状态,通过内置的FIFO队列来完成获取资源线程的排队工作。
private volatile int state;//共享变量,使用volatile修饰保证线程可见性
  1. 2种同步方式:独占式,共享式。独占式如ReentrantLock,共享式如Semaphore,

    CountDownLatch,组合式的如ReentrantReadWriteLock

  2. 节点的状态

    CANCELLED,值为1,表示当前的线程被取消;

    SIGNAL,值为-1,表示当前节点的后继节点包含的线程需要运行,也就是unpark;

    CONDITION,值为-2,表示当前节点在等待condition,也就是在condition队列中;

    PROPAGATE,值为-3,表示当前场景下后续的acquireShared能够得以执行; 值为0,表示当前节点在sync队列中,等待着获取锁。

  3. 模板方法模式

protected boolean tryAcquire(int arg) : 独占式获取同步状态,试着获取,成功返回 true,反之为false

protected boolean tryRelease(int arg) :独占式释放同步状态,等待中的其他线 程此时将有机会获取到同步状态;

protected int tryAcquireShared(int arg) :共享式获取同步状态,返回值大于等 于0,代表获取成功;反之获取失败;

protected boolean tryReleaseShared(int arg) :共享式释放同步状态,成功为 true,失败为false

AQS维护一个共享资源state,通过内置的FIFO来完成获取资源线程的排队工作。该队列 由一个一个的Node结点组成,每个Node结点维护一个prev引用和next引用,分别指向 自己的前驱和后继结点。双端双向链表。

  • 独占式:乐观的并发策略

    acquire

    a.首先tryAcquire获取同步状态,成功则直接返回;否则,进入下一环节;

    b.线程获取同步状态失败,就构造一个结点,加入同步队列中,这个过程要保证线

    程安全;

    c.加入队列中的结点线程进入自旋状态,若是老二结点(即前驱结点为头结点),才有机会尝试去获取同步状态;否则,当其前驱结点的状态为SIGNAL,线程便可安心休息,进入阻塞状态,直到被中断或者被前驱结点唤醒。

    release

    release的同步状态相对简单,需要找到头结点的后继结点进行唤醒,若后继结点为空或处于CANCEL状态,从后向前遍历找寻一个正常的结点,唤醒其对应线程。

  1. 共享式:

共享式地获取同步状态.同步状态的方法tryAcquireShared返回值为int。

a.当返回值大于0时,表示获取同步状态成功,同时还有剩余同步状态可供其他线程获 取;

b.当返回值等于0时,表示获取同步状态成功,但没有可用同步状态了;

c.当返回值小于0时,表示获取同步状态失败。

  1. AQS实现公平锁和非公平锁

    非公平锁中,那些尝试获取锁且尚未进入等待队列的线程会和等待队列head结点的线程

    发生竞争。公平锁中,在获取锁时,增加了isFirst(current)判断,当且仅当,等待队列

    为空或当前线程是等待队列的头结点时,才可尝试获取锁。