AQS源码分析

做开发也有几年了, 对1.5的concurrent并发包了解并不是很深入, 近来正好有空做个深入的学习

基础

在看 AQS 源码之前, 需要对下面的知识点有个大致的了解, 看源码会快很多

  1. Unsafe 相关, 主要是 CAS 原子锁
  2. CLH 锁
  3. 管程模型

Unsafe CAS原子锁

CAS原子锁是基于CPU的原子指令 compareAndSet 实现的命令, 该操作是原子的, 要么成功要么失败

CLH 锁

  1. CLH是一种基于队列的自旋锁
  2. 过来获取锁的线程全部排排队
  3. 只有排在第一个的线程才有执行权
  4. 其他的线程自旋判断排在前面一个节点的状态值, 不是允许执行状态则一直自旋等待

管程模型

  1. 管程模型是实现线程同步锁的一种方式, synchronized 的实现模式其实也是这个
  2. 管程主要的组成部分是: 多线程共享资源, 限制并发的进入队列, 不满足执行条件的等待队列和一些出队, 入队的方法
  3. 进入管程需要先判断是否有执行条件, 没有则在进入队列中等待
  4. 进入管程后, 不满足执行条件后, 进入等待队列等待
  5. 执行完后离开管程

代码分析

源码做了详细的注释

/**
 * 该处存在两个队列 
* 同步队列 : 争抢不到锁的线程进入同步队列
* 条件队列 : 不满足继续运行条件的await后进入条件队列 * */ @SuppressWarnings("restriction") public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable { private static final long serialVersionUID = 7373984972572414691L; protected AbstractQueuedSynchronizer() { } /** * 条件队列和同步队列的节点类 */ static final class Node { // 标记节点在共享模式下等待 static final Node SHARED = new Node(); // 标记节点在排他模式下等待 static final Node EXCLUSIVE = null; // 状态值, 表示线程已经取消了, 线程超时或者被中断 static final int CANCELLED = 1; // 节点还有一个中间状态值0, 为0是空白状态, 后面的节点也未进入park // 状态值, 表示后续节点需要被唤醒 static final int SIGNAL = -1; // 状态值, 表示线程在条件队列中, 即Condition队列, 调用Condition.await()后进入该状态值 static final int CONDITION = -2; // 状态值, 表示一下个acquireShared应该是无条件传播 static final int PROPAGATE = -3; // 节点的等待状态值 volatile int waitStatus; // Lock.lock()获取不到锁的线程进入同步队列 // 同步队列中当前节点的前面的节点 volatile Node prev; // 同步队列中当前节点的下一个节点 volatile Node next; // 当前节点的线程 volatile Thread thread; // 维持Condition条件队列的属性 // Condition.await() 等待队列中的下一个等待节点, 节点在CONDITION状态下 Node nextWaiter; // 判断节点是否在共享模式下 final boolean isShared() { return nextWaiter == SHARED; } // 获取前置节点 final Node predecessor() throws NullPointerException { Node p = prev; if (p == null) throw new NullPointerException(); else return p; } Node() { } Node(Thread thread, Node mode) { // Used by addWaiter this.nextWaiter = mode; this.thread = thread; } Node(Thread thread, int waitStatus) { // Used by Condition this.waitStatus = waitStatus; this.thread = thread; } } // 同步队列的头节点, 不为空时该节点的状态不能是CANCELLED private transient volatile Node head; // 同步队列的尾部节点, 只能通过enq添加一个新的同步节点 private transient volatile Node tail; // 线程进入同步器的次数 // state>0 说明同步锁已经被某个线程线程拿了 private volatile int state; // 获取重入次数 protected final int getState() { return state; } // 设置重入次数 protected final void setState(int newState) { state = newState; } // 设置重入次数 protected final boolean compareAndSetState(int expect, int update) { return unsafe.compareAndSwapInt(this, stateOffset, expect, update); } // Queuing utilities // 线程自旋时间 // > spinForTimeoutThreshold线程才会被park // < spinForTimeoutThreshold的将自旋 static final long spinForTimeoutThreshold = 1000L; /** * for循环强制将节点插入同步队列的尾部 * * @param 待插入的node * @return 插入前的tail */ private Node enq(final Node node) { // 因为存在并发, 需要循环执行, 直到当前把当前线程作为节点追加到同步队列尾部 for (;;) {// 循环直到将当前节点放置到等待队伍尾部 Node t = tail; if (t == null) { // 尾结点为null, 表示等待队列没有节点, 需要创建一个虚节点 if (compareAndSetHead(new Node())) tail = head; } else { node.prev = t;// node.prev=tail if (compareAndSetTail(t, node)) {// 设置当前节点为尾节点 t.next = node;// tail.next = node return t; } } } } /** * 创建线程节点, 并且添加到同步队列尾部 * * @param mode 同步模式 Node.EXCLUSIVE for exclusive, Node.SHARED for shared * @return 新创建的节点 */ private Node addWaiter(Node mode) { // 创建当前线程的等待节点 Node node = new Node(Thread.currentThread(), mode); Node pred = tail; if (pred != null) { node.prev = pred; // 该处存在并发, 需要进行原子操作 if (compareAndSetTail(pred, node)) {// 尝试将当前节点放置到等待队伍末尾 pred.next = node; return node; } } enq(node);// 上面尝试失败, 执行下面的强制放入 return node; } // 设置头节点 private void setHead(Node node) { head = node; // 用不着的属性全部设置为null node.thread = null;// help GC node.prev = null; } /** * 唤醒同步队列中的后续节点
* * @param node the node */ private void unparkSuccessor(Node node) { // 设置当前节点的等待状态值为0 int ws = node.waitStatus; if (ws < 0)// 如果节点状态<0, 将当前等待状态设置为0 compareAndSetWaitStatus(node, ws, 0);// waitStatus==0, 表示当前线程即将完成, 需要唤醒后面的节点 // unpark下一个节点, 如果下一个节点cancelled或者不存在则继续解锁下面的节点 Node s = node.next; if (s == null || s.waitStatus > 0) {// 找个下一个没有Canceled的节点, 然后唤醒 s = null; for (Node t = tail; t != null && t != node; t = t.prev) if (t.waitStatus <= 0) s = t; } if (s != null) LockSupport.unpark(s.thread);// 唤醒 } /** * 共享模式下释放锁 */ private void doReleaseShared() { // 循环解锁头节点线程, 被解锁的线程将离开等待队列, 新的头节点将会别代替 for (;;) { Node h = head; if (h != null && h != tail) { int ws = h.waitStatus; if (ws == Node.SIGNAL) {// 如果节点状态是唤醒 if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0)) continue; // 状态设置失败再次设置状态值0 unparkSuccessor(h);// 设置成功后唤醒后续节点 } else if (ws == 0 && !compareAndSetWaitStatus(h, 0, Node.PROPAGATE)) continue; // loop on failed CAS } if (h == head) // loop if head changed break; } } /** * 设置头节点然后传播 * * @param node * @param propagate */ private void setHeadAndPropagate(Node node, int propagate) { Node h = head; // Record old head for check below setHead(node); // 传播 if (propagate > 0 || h == null || h.waitStatus < 0 || (h = head) == null || h.waitStatus < 0) { Node s = node.next; if (s == null || s.isShared()) doReleaseShared(); } } // Utilities for various versions of acquire /** * 取消正在进行的获取请求
*
    *
  1. 删除当前节点
  2. *
  3. 设置后面节点的状态值SIGNAL或者唤醒后续节点
  4. *
* * @param node the node */ private void cancelAcquire(Node node) { if (node == null) return; // 节点的线程设置为null node.thread = null; // Skip cancelled 所有的前置节点 Node pred = node.prev; while (pred.waitStatus > 0) node.prev = pred = pred.prev; // waitState不为canceled的第一个前置节点的next节点 // 可能是当前节点也可能不是 Node predNext = pred.next; // 设置当前节点的等待状态为CANCELLED node.waitStatus = Node.CANCELLED; // 如果自己是tail, 则移除它 if (node == tail && compareAndSetTail(node, pred)) { compareAndSetNext(pred, predNext, null); } else { // If successor needs signal, try to set pred's next-link // so it will get one. Otherwise wake it up to propagate. int ws; if (pred != head && ((ws = pred.waitStatus) == Node.SIGNAL || (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) && pred.thread != null) { Node next = node.next; if (next != null && next.waitStatus <= 0) compareAndSetNext(pred, predNext, next);// 设置前一个节点的后一个节点, 将当前节点排除在等待队列之外 } else { // 什么情况下需要唤醒后面的节点 ? // 1.如果当前节点是头节点 // 2.不是头节点, 但是当前节点的前面的节点状态值不是SIGNAL, 但是设置SIGNAL失败时 // 3.前面的节点为null, 当前节点已经成为了新的头节点 unparkSuccessor(node); } node.next = node; // help GC } } /** * 条件: 节点的线程进入Prak状态时, 需先设置前置节点的等待状态是SIGNAL
* 因为获取锁失败后需要进入Park, 所以需要强制设置前置节点的waitStatus=SIGNAL
* 所以该方法需在for循环中使用, 循环直到前置节点的waitStatus=SIGNAL
* * @param pred node's predecessor holding status * @param node the node * @return {@code true} if thread should block */ private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { int ws = pred.waitStatus; if (ws == Node.SIGNAL) // 前节点状态为-1, 说明当前节点需要被唤醒 return true; if (ws > 0) {// 状态>0是节点都是CANCELLED // 前节点状态>0, 找到前状态<=0的节点连在它的后面 do { node.prev = pred = pred.prev; } while (pred.waitStatus > 0); pred.next = node; } else { // 前节点状态<0时, 设置前节点的等待状态为-1 // 下一个循环就可以将当前线程Park compareAndSetWaitStatus(pred, ws, Node.SIGNAL); } return false; } // 打断当前线程, 目的是重置中断标识位 static void selfInterrupt() { Thread.currentThread().interrupt(); } /** * Park当前线程, 等待中断获取unpark * * @return 线程是否被中断唤醒 */ private final boolean parkAndCheckInterrupt() { LockSupport.park(this);// 当前线程Park, 等待被unpark获取被中断 return Thread.interrupted();// 该方法会重置中断位, 后续的操作需要重新设置中断位 } /** * 节点请求排队
* 节点已经进入同步队列中排队, 排队中再次尝试获取锁
* 如果获取不到则设置前置节点的waitStatus=SIGNAL后Park等待 * * @param node 当前节点 * @param arg 锁重入次数 * @return 排队被中断返回true, 正常唤醒返回false */ final boolean acquireQueued(final Node node, int arg) { boolean failed = true; try { boolean interrupted = false; // 第一个是虚节点, 当节点是第二个时就可以抢资源了, 如果获取锁成功了, 下面就不需要执行直接返回 // 其他情况是设置前节点的等待状态为-1, 线程Park后等待唤醒 // for循环, 该处必须要是循环之内, 线程要是被中断唤醒后, 没有抢到锁继续Park for (;;) { final Node p = node.predecessor();// 前节点 if (p == head && tryAcquire(arg)) {// 前面节点是头节点, 而且获取到了锁 setHead(node);// 释放前节点 p.next = null; // help GC failed = false; return interrupted; } if (shouldParkAfterFailedAcquire(p, node)// 强制设置前置节点的waitStatus=SIGNAL && parkAndCheckInterrupt())// Park当前线程 interrupted = true;// 不是中断唤醒不执行 } } finally { if (failed)// 上面的操作出现异常, 取消当前线程的请求 cancelAcquire(node); } } /** * 排他模式下, 先获取锁, 获取不到则Park, 如果线程被打断则抛出InterruptedException * * @param arg 重入锁的次数 * @throws InterruptedException */ private void doAcquireInterruptibly(int arg) throws InterruptedException { final Node node = addWaiter(Node.EXCLUSIVE);// 添加排他等待者 boolean failed = true; try { for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC failed = false; return; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } } /** * 在时间限定下请求锁, 每个多少个ns时间周期请求锁 * * @param arg the acquire argument * @param nanosTimeout max wait time * @return {@code true} if acquired */ private boolean doAcquireNanos(int arg, long nanosTimeout) throws InterruptedException { if (nanosTimeout <= 0L) return false; final long deadline = System.nanoTime() + nanosTimeout; final Node node = addWaiter(Node.EXCLUSIVE);// 添加到等待队列 boolean failed = true; try { for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) {// 获取到锁则执行 setHead(node); p.next = null; // help GC failed = false; return true; } nanosTimeout = deadline - System.nanoTime(); if (nanosTimeout <= 0L) return false; if (shouldParkAfterFailedAcquire(p, node)// 线程应该park && nanosTimeout > spinForTimeoutThreshold// 等待时间>自旋超时时间 ) LockSupport.parkNanos(this, nanosTimeout);// 线程Park if (Thread.interrupted())// 线程被打断则抛出异常, 没有打断则继续请求锁 throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } } /** * 共享模式下请求锁 * * @param arg the acquire argument */ private void doAcquireShared(int arg) { final Node node = addWaiter(Node.SHARED); boolean failed = true; try { boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head) { int r = tryAcquireShared(arg); if (r >= 0) { setHeadAndPropagate(node, r); p.next = null; // help GC if (interrupted) selfInterrupt(); failed = false; return; } } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally { if (failed) cancelAcquire(node); } } /** * 共享模式下请求锁, 抛出异常 * * @param arg the acquire argument */ private void doAcquireSharedInterruptibly(int arg) throws InterruptedException { final Node node = addWaiter(Node.SHARED); boolean failed = true; try { for (;;) { final Node p = node.predecessor(); if (p == head) { int r = tryAcquireShared(arg); if (r >= 0) { setHeadAndPropagate(node, r); p.next = null; // help GC failed = false; return; } } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } } /** * 共享模式下时间间隔请求锁 * * @param arg the acquire argument * @param nanosTimeout max wait time * @return {@code true} if acquired */ private boolean doAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException { if (nanosTimeout <= 0L) return false; final long deadline = System.nanoTime() + nanosTimeout; final Node node = addWaiter(Node.SHARED); boolean failed = true; try { for (;;) { final Node p = node.predecessor(); if (p == head) { int r = tryAcquireShared(arg); if (r >= 0) { setHeadAndPropagate(node, r); p.next = null; // help GC failed = false; return true; } } nanosTimeout = deadline - System.nanoTime(); if (nanosTimeout <= 0L) return false; if (shouldParkAfterFailedAcquire(p, node) && nanosTimeout > spinForTimeoutThreshold) LockSupport.parkNanos(this, nanosTimeout); if (Thread.interrupted()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } } // Main exported methods /** * 请求锁, 该处实现需要注意并发情况, 使用CAS原子锁执行操作 * * @param arg * @return */ protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); } /** * 释放排他锁
* 1. 设置同步器state=0
* 2. 设置同步器排他线程为null * * @param arg * @return */ protected boolean tryRelease(int arg) { throw new UnsupportedOperationException(); } /** * 共享模式下获取锁 * * @param arg * @return */ protected int tryAcquireShared(int arg) { throw new UnsupportedOperationException(); } /** * 共享模式下释放锁 * * @param arg * @return */ protected boolean tryReleaseShared(int arg) { throw new UnsupportedOperationException(); } // 判断当前线程是否持有锁 protected boolean isHeldExclusively() { throw new UnsupportedOperationException(); } /** * 先请求锁, 请求不到则到等待队列 * * @param arg */ public final void acquire(int arg) { // tryAcquire请求锁, 请求成功离开 // 请求不成功继续执行acquireQueued, 请求线程入同步队列末等待 if (!tryAcquire(arg)// 抢锁 && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)// 抢不到排队, 返回值是精心设计的 ) // 锁请求失败, 线程Park被中断时执行下面的方法 selfInterrupt();// 重置中断 } /** * 先请求锁, 请求不到则到等待队列 * * @param arg * @throws InterruptedException */ public final void acquireInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (!tryAcquire(arg)) doAcquireInterruptibly(arg); } /** * 尝试获取排他锁, 获取不到则间隔获取 * * @param arg the acquire argument. This value is conveyed to * {@link #tryAcquire} but is otherwise uninterpreted and * can represent anything you like. * @param nanosTimeout the maximum number of nanoseconds to wait * @return {@code true} if acquired; {@code false} if timed out * @throws InterruptedException if the current thread is interrupted */ public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); return tryAcquire(arg) || doAcquireNanos(arg, nanosTimeout); } /** * 释放锁, 释放完成后唤醒后续节点 * * @param arg the release argument. This value is conveyed to * {@link #tryRelease} but is otherwise uninterpreted and can * represent anything you like. * @return the value returned from {@link #tryRelease} */ public final boolean release(int arg) { if (tryRelease(arg)) { Node h = head; // 需要判断当前节点的waitStatus值 // 后面节点在进入Park是会将前面的waitStatus设置为-1, 如果是-1时就需要唤醒后面的线程节点 if (h != null && h.waitStatus != 0) unparkSuccessor(h);// 唤醒后面的节点 return true; } return false; } /** * Acquires in shared mode, ignoring interrupts. Implemented by first invoking * at least once {@link #tryAcquireShared}, returning on success. Otherwise the * thread is queued, possibly repeatedly blocking and unblocking, invoking * {@link #tryAcquireShared} until success. * * @param arg the acquire argument. This value is conveyed to * {@link #tryAcquireShared} but is otherwise uninterpreted and can * represent anything you like. */ public final void acquireShared(int arg) { if (tryAcquireShared(arg) < 0) doAcquireShared(arg); } /** * Acquires in shared mode, aborting if interrupted. Implemented by first * checking interrupt status, then invoking at least once * {@link #tryAcquireShared}, returning on success. Otherwise the thread is * queued, possibly repeatedly blocking and unblocking, invoking * {@link #tryAcquireShared} until success or the thread is interrupted. * * @param arg the acquire argument. This value is conveyed to * {@link #tryAcquireShared} but is otherwise uninterpreted and can * represent anything you like. * @throws InterruptedException if the current thread is interrupted */ public final void acquireSharedInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (tryAcquireShared(arg) < 0) doAcquireSharedInterruptibly(arg); } /** * Attempts to acquire in shared mode, aborting if interrupted, and failing if * the given timeout elapses. Implemented by first checking interrupt status, * then invoking at least once {@link #tryAcquireShared}, returning on success. * Otherwise, the thread is queued, possibly repeatedly blocking and unblocking, * invoking {@link #tryAcquireShared} until success or the thread is interrupted * or the timeout elapses. * * @param arg the acquire argument. This value is conveyed to * {@link #tryAcquireShared} but is otherwise uninterpreted * and can represent anything you like. * @param nanosTimeout the maximum number of nanoseconds to wait * @return {@code true} if acquired; {@code false} if timed out * @throws InterruptedException if the current thread is interrupted */ public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); return tryAcquireShared(arg) >= 0 || doAcquireSharedNanos(arg, nanosTimeout); } /** * Releases in shared mode. Implemented by unblocking one or more threads if * {@link #tryReleaseShared} returns true. * * @param arg the release argument. This value is conveyed to * {@link #tryReleaseShared} but is otherwise uninterpreted and can * represent anything you like. * @return the value returned from {@link #tryReleaseShared} */ public final boolean releaseShared(int arg) { if (tryReleaseShared(arg)) { doReleaseShared(); return true; } return false; } // Queue inspection methods /** * 等待队列中是否还有等待线程 * *

* In this implementation, this operation returns in constant time. * * @return {@code true} if there may be other threads waiting to acquire */ public final boolean hasQueuedThreads() { return head != tail; } /** * 等待队列中是否还有内容 * *

* In this implementation, this operation returns in constant time. * * @return {@code true} if there has ever been contention */ public final boolean hasContended() { return head != null; } /** * Returns the first (longest-waiting) thread in the queue, or {@code null} if * no threads are currently queued. * *

* In this implementation, this operation normally returns in constant time, but * may iterate upon contention if other threads are concurrently modifying the * queue. * * @return the first (longest-waiting) thread in the queue, or {@code null} if * no threads are currently queued */ public final Thread getFirstQueuedThread() { // handle only fast path, else relay return (head == tail) ? null : fullGetFirstQueuedThread(); } /** * Version of getFirstQueuedThread called when fastpath fails */ private Thread fullGetFirstQueuedThread() { /* * The first node is normally head.next. Try to get its thread field, ensuring * consistent reads: If thread field is nulled out or s.prev is no longer head, * then some other thread(s) concurrently performed setHead in between some of * our reads. We try this twice before resorting to traversal. */ Node h, s; Thread st; if (((h = head) != null && (s = h.next) != null && s.prev == head && (st = s.thread) != null) || ((h = head) != null && (s = h.next) != null && s.prev == head && (st = s.thread) != null)) return st; /* * Head's next field might not have been set yet, or may have been unset after * setHead. So we must check to see if tail is actually first node. If not, we * continue on, safely traversing from tail back to head to find first, * guaranteeing termination. */ Node t = tail; Thread firstThread = null; while (t != null && t != head) { Thread tt = t.thread; if (tt != null) firstThread = tt; t = t.prev; } return firstThread; } /** * 判断线程是否已经进入等待队列 * *

* 遍历等待队列检查线程是否存在 * * @param thread the thread * @return {@code true} if the given thread is on the queue * @throws NullPointerException if the thread is null */ public final boolean isQueued(Thread thread) { if (thread == null) throw new NullPointerException(); for (Node p = tail; p != null; p = p.prev) if (p.thread == thread) return true; return false; } /** * 判断排队个第一个是否是排他模式节点 */ final boolean apparentlyFirstQueuedIsExclusive() { Node h, s; return (h = head) != null && (s = h.next) != null && !s.isShared() && s.thread != null; } /** * 检查我前面是否还有别的线程在等待 * * @return */ public final boolean hasQueuedPredecessors() { Node t = tail; // Read fields in reverse initialization order Node h = head; Node s; return h != t && ((s = h.next) == null || s.thread != Thread.currentThread()); } // Instrumentation and monitoring methods /** * 获取节点的排队的队伍长度 * * @return the estimated number of threads waiting to acquire */ public final int getQueueLength() { int n = 0; for (Node p = tail; p != null; p = p.prev) { if (p.thread != null) ++n; } return n; } /** * 获取所有的排队线程 * * @return the collection of threads */ public final Collection getQueuedThreads() { ArrayList list = new ArrayList(); for (Node p = tail; p != null; p = p.prev) { Thread t = p.thread; if (t != null) list.add(t); } return list; } /** * 获取所有的排他模式的排队线程 * * @return the collection of threads */ public final Collection getExclusiveQueuedThreads() { ArrayList list = new ArrayList(); for (Node p = tail; p != null; p = p.prev) { if (!p.isShared()) { Thread t = p.thread; if (t != null) list.add(t); } } return list; } /** * 获取所有的共享模式下的排队线程 * * @return the collection of threads */ public final Collection getSharedQueuedThreads() { ArrayList list = new ArrayList(); for (Node p = tail; p != null; p = p.prev) { if (p.isShared()) { Thread t = p.thread; if (t != null) list.add(t); } } return list; } /** * AQS toString * * @return a string identifying this synchronizer, as well as its state */ public String toString() { int s = getState(); String q = hasQueuedThreads() ? "non" : ""; return super.toString() + "[State = " + s + ", " + q + "empty queue]"; } // Internal support methods for Conditions /** * 当前节点是否在同步队列中 * * @param node the node * @return true if is reacquiring */ final boolean isOnSyncQueue(Node node) { // 节点状态是CONDITION, 或者节点没有前置节点, 说明节点不在队列里面 if (node.waitStatus == Node.CONDITION// 节点状态是await, 那肯定是不在同步队列中, 应该在等待队列里面 || node.prev == null// 前一个节点是null, 则是头节点, 那肯定不需要进行同步 ) return false; // 节点有后置节点, 说明节点肯定在 if (node.next != null) // If has successor, it must be on queue return true; return findNodeFromTail(node); } /** * 从等待队列的最后往前遍历, 检测节点是的在排队 * * @return true if present */ private boolean findNodeFromTail(Node node) { Node t = tail; for (;;) { if (t == node) return true; if (t == null) return false; t = t.prev; } } /** * 将节点从条件队列转换到同步队列 * * @param node the node * @return true if successfully transferred (else the node was cancelled before * signal) */ final boolean transferForSignal(Node node) { // 节点状态转换为0 if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) // 节点状态转换失败 return false; // 节点加入到同步队列尾 Node p = enq(node);// 前置节点 int ws = p.waitStatus; if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL)) // 前面的节点取消了, 或者前面节点设置SIGNAL失败, 当前节点unpark LockSupport.unpark(node.thread); return true; } /** * Transfers node, if necessary, to sync queue after a cancelled wait. Returns * true if thread was cancelled before being signalled. * * @param node the node * @return true if cancelled before the node was signalled */ final boolean transferAfterCancelledWait(Node node) { if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) { enq(node); return true; } /* * If we lost out to a signal(), then we can't proceed until it finishes its * enq(). Cancelling during an incomplete transfer is both rare and transient, * so just spin. */ while (!isOnSyncQueue(node)) Thread.yield(); return false; } /** * 释放所有的可重入的锁 * * @param node * @return */ final int fullyRelease(Node node) { boolean failed = true; try { int savedState = getState();// 锁的重入数量 if (release(savedState)) {// 释放全部 failed = false; return savedState; } else { throw new IllegalMonitorStateException(); } } finally { if (failed) node.waitStatus = Node.CANCELLED; } } // Instrumentation methods for conditions /** * Queries whether the given ConditionObject uses this synchronizer as its lock. * * @param condition the condition * @return {@code true} if owned * @throws NullPointerException if the condition is null */ public final boolean owns(ConditionObject condition) { return condition.isOwnedBy(this); } /** * Queries whether any threads are waiting on the given condition associated * with this synchronizer. Note that because timeouts and interrupts may occur * at any time, a {@code true} return does not guarantee that a future * {@code signal} will awaken any threads. This method is designed primarily for * use in monitoring of the system state. * * @param condition the condition * @return {@code true} if there are any waiting threads * @throws IllegalMonitorStateException if exclusive synchronization is not held * @throws IllegalArgumentException if the given condition is not associated * with this synchronizer * @throws NullPointerException if the condition is null */ public final boolean hasWaiters(ConditionObject condition) { if (!owns(condition)) throw new IllegalArgumentException("Not owner"); return condition.hasWaiters(); } /** * Returns an estimate of the number of threads waiting on the given condition * associated with this synchronizer. Note that because timeouts and interrupts * may occur at any time, the estimate serves only as an upper bound on the * actual number of waiters. This method is designed for use in monitoring of * the system state, not for synchronization control. * * @param condition the condition * @return the estimated number of waiting threads * @throws IllegalMonitorStateException if exclusive synchronization is not held * @throws IllegalArgumentException if the given condition is not associated * with this synchronizer * @throws NullPointerException if the condition is null */ public final int getWaitQueueLength(ConditionObject condition) { if (!owns(condition)) throw new IllegalArgumentException("Not owner"); return condition.getWaitQueueLength(); } /** * Returns a collection containing those threads that may be waiting on the * given condition associated with this synchronizer. Because the actual set of * threads may change dynamically while constructing this result, the returned * collection is only a best-effort estimate. The elements of the returned * collection are in no particular order. * * @param condition the condition * @return the collection of threads * @throws IllegalMonitorStateException if exclusive synchronization is not held * @throws IllegalArgumentException if the given condition is not associated * with this synchronizer * @throws NullPointerException if the condition is null */ public final Collection getWaitingThreads(ConditionObject condition) { if (!owns(condition)) throw new IllegalArgumentException("Not owner"); return condition.getWaitingThreads(); } /** * 条件对象, 获取到锁的线程的进入await的队列 */ public class ConditionObject implements Condition, java.io.Serializable { private static final long serialVersionUID = 1173984872572414699L; // 条件队列的第一个元素 private transient Node firstWaiter; // 条件队列的最后一个元素 private transient Node lastWaiter; public ConditionObject() { } // Internal methods /** * 将当前线程添加到条件队列中 * * @return 当前线程的队列节点 */ private Node addConditionWaiter() { Node t = lastWaiter; // If lastWaiter is cancelled, clean out. if (t != null && t.waitStatus != Node.CONDITION) { unlinkCancelledWaiters(); t = lastWaiter; } Node node = new Node(Thread.currentThread(), Node.CONDITION); if (t == null) firstWaiter = node; else t.nextWaiter = node; lastWaiter = node; return node; } /** * 移除canceled节点, 将条件队列转换为同步队列 * * @param first (non-null) the first node on condition queue */ private void doSignal(Node first) { do { if ((firstWaiter = first.nextWaiter) == null)// 下一个waiter设置为firstWaiter lastWaiter = null;// 下一个waiter为null, 设置lastWaiter=null first.nextWaiter = null;// 清除nextWaiter } while (!transferForSignal(first) && (first = firstWaiter) != null); } /** * 将所有的条件队列转换为同步队列 * * @param first (non-null) the first node on condition queue */ private void doSignalAll(Node first) { lastWaiter = firstWaiter = null; do { Node next = first.nextWaiter; first.nextWaiter = null; transferForSignal(first); first = next; } while (first != null); } /** * 删除条件队列中所有waitStatus!=CONDITION的节点 */ private void unlinkCancelledWaiters() { Node t = firstWaiter; Node trail = null;// 追踪遍历过程中节点状态是CONDITION的最新的节点 while (t != null) { Node next = t.nextWaiter;// 下一个节点 if (t.waitStatus != Node.CONDITION) {// 当前节点的状态不是 CONDITION t.nextWaiter = null;// 清除 if (trail == null)// firstWaiter = next; else trail.nextWaiter = next; if (next == null)// await队列尾 lastWaiter = trail; } else trail = t; t = next; } } // public methods /** * 唤醒等待队列的第一个线程 */ public final void signal() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); Node first = firstWaiter; if (first != null) doSignal(first); } /** * 唤醒所有条件队列的等待节点 * * @throws IllegalMonitorStateException if {@link #isHeldExclusively} returns * {@code false} */ public final void signalAll() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); Node first = firstWaiter; if (first != null) doSignalAll(first); } /** * Implements uninterruptible condition wait. *

    *
  1. Save lock state returned by {@link #getState}. *
  2. Invoke {@link #release} with saved state as argument, throwing * IllegalMonitorStateException if it fails. *
  3. Block until signalled. *
  4. Reacquire by invoking specialized version of {@link #acquire} with saved * state as argument. *
*/ public final void awaitUninterruptibly() { Node node = addConditionWaiter(); int savedState = fullyRelease(node); boolean interrupted = false; while (!isOnSyncQueue(node)) { LockSupport.park(this); if (Thread.interrupted()) interrupted = true; } if (acquireQueued(node, savedState) || interrupted) selfInterrupt(); } // 出队列后重新打断 private static final int REINTERRUPT = 1; // 出队列后throw InterruptedException private static final int THROW_IE = -1; /** * Checks for interrupt, returning THROW_IE if interrupted before signalled, * REINTERRUPT if after signalled, or 0 if not interrupted. */ private int checkInterruptWhileWaiting(Node node) { return Thread.interrupted() ? (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) : 0; } /** * Throws InterruptedException, reinterrupts current thread, or does nothing, * depending on mode. */ private void reportInterruptAfterWait(int interruptMode) throws InterruptedException { if (interruptMode == THROW_IE) throw new InterruptedException(); else if (interruptMode == REINTERRUPT) selfInterrupt(); } /** * Implements interruptible condition wait. *
    *
  1. 如果当前线程被打断则抛出异常 *
  2. Save lock state returned by {@link #getState}. *
  3. 请求Invoke {@link #release} 释放上面获取lock状态, 失败则抛出IllegalMonitorStateException *
  4. 阻塞等待唤醒或者打断 *
  5. 重新争抢锁, 抢到则继续运行 *
  6. If interrupted while blocked in step 4, throw InterruptedException. *
*/ public final void await() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter();// 将线程添加到await队列 int savedState = fullyRelease(node);// 释放所有的重入锁 int interruptMode = 0;// while (!isOnSyncQueue(node)) {// 检查线程是否在同步队列中 // 不在同同步队列中就应该阻塞 LockSupport.park(this);// park if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; } // 请求锁, 请求不到进入同步队列等待 if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) // clean up if cancelled unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); } /** * Implements timed condition wait. *
    *
  1. If current thread is interrupted, throw InterruptedException. *
  2. Save lock state returned by {@link #getState}. *
  3. Invoke {@link #release} with saved state as argument, throwing * IllegalMonitorStateException if it fails. *
  4. Block until signalled, interrupted, or timed out. *
  5. Reacquire by invoking specialized version of {@link #acquire} with saved * state as argument. *
  6. If interrupted while blocked in step 4, throw InterruptedException. *
*/ public final long awaitNanos(long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); int savedState = fullyRelease(node); final long deadline = System.nanoTime() + nanosTimeout; int interruptMode = 0; while (!isOnSyncQueue(node)) { if (nanosTimeout <= 0L) { transferAfterCancelledWait(node); break; } if (nanosTimeout >= spinForTimeoutThreshold) LockSupport.parkNanos(this, nanosTimeout); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; nanosTimeout = deadline - System.nanoTime(); } if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); return deadline - System.nanoTime(); } /** * Implements absolute timed condition wait. *
    *
  1. If current thread is interrupted, throw InterruptedException. *
  2. Save lock state returned by {@link #getState}. *
  3. Invoke {@link #release} with saved state as argument, throwing * IllegalMonitorStateException if it fails. *
  4. Block until signalled, interrupted, or timed out. *
  5. Reacquire by invoking specialized version of {@link #acquire} with saved * state as argument. *
  6. If interrupted while blocked in step 4, throw InterruptedException. *
  7. If timed out while blocked in step 4, return false, else true. *
*/ public final boolean awaitUntil(Date deadline) throws InterruptedException { long abstime = deadline.getTime(); if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); int savedState = fullyRelease(node); boolean timedout = false; int interruptMode = 0; while (!isOnSyncQueue(node)) { if (System.currentTimeMillis() > abstime) { timedout = transferAfterCancelledWait(node); break; } LockSupport.parkUntil(this, abstime); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; } if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); return !timedout; } /** * Implements timed condition wait. *
    *
  1. If current thread is interrupted, throw InterruptedException. *
  2. Save lock state returned by {@link #getState}. *
  3. Invoke {@link #release} with saved state as argument, throwing * IllegalMonitorStateException if it fails. *
  4. Block until signalled, interrupted, or timed out. *
  5. Reacquire by invoking specialized version of {@link #acquire} with saved * state as argument. *
  6. If interrupted while blocked in step 4, throw InterruptedException. *
  7. If timed out while blocked in step 4, return false, else true. *
*/ public final boolean await(long time, TimeUnit unit) throws InterruptedException { long nanosTimeout = unit.toNanos(time); if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); int savedState = fullyRelease(node); final long deadline = System.nanoTime() + nanosTimeout; boolean timedout = false; int interruptMode = 0; while (!isOnSyncQueue(node)) { if (nanosTimeout <= 0L) { timedout = transferAfterCancelledWait(node); break; } if (nanosTimeout >= spinForTimeoutThreshold) LockSupport.parkNanos(this, nanosTimeout); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; nanosTimeout = deadline - System.nanoTime(); } if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); return !timedout; } // support for instrumentation /** * Returns true if this condition was created by the given synchronization * object. * * @return {@code true} if owned */ final boolean isOwnedBy(AbstractQueuedSynchronizer sync) { return sync == AbstractQueuedSynchronizer.this; } /** * Queries whether any threads are waiting on this condition. Implements * {@link AbstractQueuedSynchronizer#hasWaiters(ConditionObject)}. * * @return {@code true} if there are any waiting threads * @throws IllegalMonitorStateException if {@link #isHeldExclusively} returns * {@code false} */ protected final boolean hasWaiters() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); for (Node w = firstWaiter; w != null; w = w.nextWaiter) { if (w.waitStatus == Node.CONDITION) return true; } return false; } /** * Returns an estimate of the number of threads waiting on this condition. * Implements * {@link AbstractQueuedSynchronizer#getWaitQueueLength(ConditionObject)}. * * @return the estimated number of waiting threads * @throws IllegalMonitorStateException if {@link #isHeldExclusively} returns * {@code false} */ protected final int getWaitQueueLength() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); int n = 0; for (Node w = firstWaiter; w != null; w = w.nextWaiter) { if (w.waitStatus == Node.CONDITION) ++n; } return n; } /** * Returns a collection containing those threads that may be waiting on this * Condition. Implements * {@link AbstractQueuedSynchronizer#getWaitingThreads(ConditionObject)}. * * @return the collection of threads * @throws IllegalMonitorStateException if {@link #isHeldExclusively} returns * {@code false} */ protected final Collection getWaitingThreads() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); ArrayList list = new ArrayList(); for (Node w = firstWaiter; w != null; w = w.nextWaiter) { if (w.waitStatus == Node.CONDITION) { Thread t = w.thread; if (t != null) list.add(t); } } return list; } } private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long stateOffset; private static final long headOffset; private static final long tailOffset; private static final long waitStatusOffset; private static final long nextOffset; static { try { stateOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField("state")); headOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField("head")); tailOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField("tail")); waitStatusOffset = unsafe.objectFieldOffset(Node.class.getDeclaredField("waitStatus")); nextOffset = unsafe.objectFieldOffset(Node.class.getDeclaredField("next")); } catch (Exception ex) { throw new Error(ex); } } // 设置头节点 private final boolean compareAndSetHead(Node update) { return unsafe.compareAndSwapObject(this, headOffset, null, update); } // 设置等待队列的尾节点 private final boolean compareAndSetTail(Node expect, Node update) { return unsafe.compareAndSwapObject(this, tailOffset, expect, update); } // 设置节点的等待状态值 private static final boolean compareAndSetWaitStatus(Node node, int expect, int update) { return unsafe.compareAndSwapInt(node, waitStatusOffset, expect, update); } // 设置当前节点的下一个节点值 private static final boolean compareAndSetNext(Node node, Node expect, Node update) { return unsafe.compareAndSwapObject(node, nextOffset, expect, update); } }

你可能感兴趣的:(AQS源码分析)