/** * Performs non-fair tryLock. tryAcquire is implemented in * subclasses, but both need nonfair try for trylock method. */ finalbooleannonfairTryAcquire(int acquires){ final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); returntrue; } } elseif (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow thrownew Error("Maximum lock count exceeded"); setState(nextc); returntrue; } returnfalse; } }
/** * Fair version of tryAcquire. Don't grant access unless * recursive call or no waiters or is first. */ protectedfinalbooleantryAcquire(int acquires){ final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { // 先判断当前线程是否位于等待队列中的第一个 if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); returntrue; } } elseif (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) thrownew Error("Maximum lock count exceeded"); setState(nextc); returntrue; } returnfalse; } }
if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); returntrue; }
publicfinalbooleanhasQueuedPredecessors(){ // The correctness of this depends on head being initialized // before tail and on head.next being accurate if the current // thread is first in queue. 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()); }
privatevoiddoSignal(Node first){ do { // 移除头结点 if ( (firstWaiter = first.nextWaiter) == null) lastWaiter = null; first.nextWaiter = null; } while (!transferForSignal(first) && (first = firstWaiter) != null); }
finalbooleantransferForSignal(Node node){
if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) returnfalse;
Node p = enq(node); int ws = p.waitStatus; // 仅在前驱节点的状态处于取消状态或设置前驱节点状态为 SIGNAL 失败时才会直接唤醒 // 大部分情况都不会在这里唤醒 if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL)) LockSupport.unpark(node.thread); returntrue; }
signal 方法的主要逻辑如下:
首先它会将头结点从 Condition 队列取出
然后通过 enq 将当前线程加入 AQS 队列尾
仅在前驱节点的状态处于取消状态或设置前驱节点状态为 SIGNAL 失败时才会直接唤醒,否则是等待它在 AQS 队列的前驱结点释放锁后唤醒(这样它的前驱结点为头结点,它才有资格获取锁,唤醒才有意义)
signalAll
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
publicfinalvoidsignalAll(){ if (!isHeldExclusively()) thrownew IllegalMonitorStateException(); Node first = firstWaiter; if (first != null) doSignalAll(first); }
privatevoiddoSignalAll(Node first){ lastWaiter = firstWaiter = null; do { Node next = first.nextWaiter; first.nextWaiter = null; transferForSignal(first); first = next; } while (first != null); }
signalAll 和 signal 的区别就在于它会遍历 Condition 队列,把所有 Condition 队列中的结点放入 AQS 队列等待唤醒。