- AQS使用一个int成员变量来表示同步状态,通过内置的FIFO队列来完成获取资源线程的排队工作。
private volatile int state;//共享变量,使用volatile修饰保证线程可见性
-
2种同步方式:独占式,共享式。独占式如ReentrantLock,共享式如Semaphore,
CountDownLatch,组合式的如ReentrantReadWriteLock
-
节点的状态
CANCELLED,值为1,表示当前的线程被取消;
SIGNAL,值为-1,表示当前节点的后继节点包含的线程需要运行,也就是unpark;
CONDITION,值为-2,表示当前节点在等待condition,也就是在condition队列中;
PROPAGATE,值为-3,表示当前场景下后续的acquireShared能够得以执行; 值为0,表示当前节点在sync队列中,等待着获取锁。
-
模板方法模式
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状态,从后向前遍历找寻一个正常的结点,唤醒其对应线程。
- 共享式:
共享式地获取同步状态.同步状态的方法tryAcquireShared返回值为int。
a.当返回值大于0时,表示获取同步状态成功,同时还有剩余同步状态可供其他线程获 取;
b.当返回值等于0时,表示获取同步状态成功,但没有可用同步状态了;
c.当返回值小于0时,表示获取同步状态失败。
-
AQS实现公平锁和非公平锁
非公平锁中,那些尝试获取锁且尚未进入等待队列的线程会和等待队列head结点的线程
发生竞争。公平锁中,在获取锁时,增加了isFirst(current)判断,当且仅当,等待队列
为空或当前线程是等待队列的头结点时,才可尝试获取锁。