Last updated on 2025-11-23T21:10:49+08:00
1. TODO
2. 脑图
Xmind
Edraw

Hexo 地址
👉 http://blog.wangjia.ink/2025/08/31/源码:java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject源码解析/
3. 基础部分
3.1. AbstractQueuedSynchronizer.ConditionObject 概述
ConditionObject 是一个具体类,是 java.util.concurrent.locks.AbstractQueuedSynchronizer. 的普通内部类,实现了 java.util.concurrent.locks.Condition、java.io.Serializable

ConditionObject 维护了一个由 AbstractQueuedSynchronizer.ConditionNode 构建的,基于单向链表的队列。所谓的 “AQS 的条件队列” 其实就是在说 ConditionObject 维护的这条件队列

[!NOTE] 注意事项
- 详见源码:
AbstractQueuedSynchronizer
obsidian 内部链接:
- 源码:java.util.concurrent.locks.AbstractQueuedSynchronizer源码解析
Hexo 链接:
- http://blog.wangjia.ink/2025/09/01/源码:java.util.concurrent.locks.AbstractQueuedSynchronizer源码解析/
- 详见源码:
Condition
obsidian 内部链接:
- 源码:java.util.concurrent.locks.Condition源码解析
Hexo 链接:
- http://blog.wangjia.ink/2025/08/31/源码:java.util.concurrent.locks.Condition源码解析/
- 详见源码:
Serializable
obsidian 内部链接:
- 源码:java.io.Serializable源码解析
Hexo 链接:
- http://blog.wangjia.ink/2025/10/28/源码:java.io.Serializable源码解析/
4. 核心属性
1 2 3 4 5
| private transient ConditionNode firstWaiter;
private transient ConditionNode lastWaiter;
|
5. 具体方法
5.1. 具体方法(无)
5.1.1. private int enableWait(ConditionNode node)
private int enableWait(ConditionNode node) 用于 把当前线程包装成一个 ConditionNode,然后将该节点链接到条件队列(单向链表)中,并释放锁资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
private int enableWait(ConditionNode node) { if (isHeldExclusively()) { node.waiter = Thread.currentThread(); node.setStatusRelaxed(COND | WAITING); ConditionNode last = lastWaiter; if (last == null) firstWaiter = node; else last.nextWaiter = node; lastWaiter = node; int savedState = getState(); if (release(savedState)) return savedState; } node.status = CANCELLED; throw new IllegalMonitorStateException(); }
|
5.1.2. private boolean canReacquire(ConditionNode node)
private boolean canReacquire(ConditionNode node) 用于 判断某个在 Condition 上等待的节点,被 Condition 的 signal 后,是否已经链接到同步队列中
需要注意的是,线程在被 Condition 的 signal() 唤醒后,按设计一定会转移到同步队列中去竞争锁。但在高并发环境下,节点的入队过程并非一步到位,可能出现链表指针尚未完全修复或节点已被取消等等 “中间态”。因此,需要通过这个方法进行校验,确保节点确实已经稳定地进入同步队列,才算真正具备重新竞争锁的资格。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| private boolean canReacquire(ConditionNode node) { Node p;
return node != null && (p = node.prev) != null && (p.next == node || isEnqueued(node)); }
|
5.1.3. private void doSignal(ConditionNode first, boolean all)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| private void doSignal(ConditionNode first, boolean all) { while (first != null) { ConditionNode next = first.nextWaiter; if ((firstWaiter = next) == null) lastWaiter = null;
if ((first.getAndUnsetStatus(COND) & COND) != 0) { enqueue(first); if (!all) break; } first = next; } }
|
5.2. 具体方法(实现)
5.2.1. Condition 中的方法实现
5.2.1.1. public final void await()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public final void await() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); ConditionNode node = new ConditionNode(); int savedState = enableWait(node); LockSupport.setCurrentBlocker(this); boolean interrupted = false, cancelled = false, rejected = false; while (!canReacquire(node)) { if (interrupted |= Thread.interrupted()) { if (cancelled = (node.getAndUnsetStatus(COND) & COND) != 0) break; } else if ((node.status & COND) != 0) { try { if (rejected) node.block(); else ForkJoinPool.managedBlock(node); } catch (RejectedExecutionException ex) { rejected = true; } catch (InterruptedException ie) { interrupted = true; } } else Thread.onSpinWait(); } LockSupport.setCurrentBlocker(null); node.clearStatus(); acquire(node, savedState, false, false, false, 0L); if (interrupted) { if (cancelled) { unlinkCancelledWaiters(node); throw new InterruptedException(); } Thread.currentThread().interrupt(); } }
|
5.2.1.2. public final void awaitUninterruptibly()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public final void awaitUninterruptibly() { ConditionNode node = new ConditionNode(); int savedState = enableWait(node); LockSupport.setCurrentBlocker(this); boolean interrupted = false, rejected = false; while (!canReacquire(node)) { if (Thread.interrupted()) interrupted = true; else if ((node.status & COND) != 0) { try { if (rejected) node.block(); else ForkJoinPool.managedBlock(node); } catch (RejectedExecutionException ex) { rejected = true; } catch (InterruptedException ie) { interrupted = true; }
} else Thread.onSpinWait(); } LockSupport.setCurrentBlocker(null); node.clearStatus(); acquire(node, savedState, false, false, false, 0L); if (interrupted) Thread.currentThread().interrupt(); }
|
5.2.1.3. public final long awaitNanos(long nanosTimeout)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public final long awaitNanos(long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); ConditionNode node = new ConditionNode(); int savedState = enableWait(node); long nanos = (nanosTimeout < 0L) ? 0L : nanosTimeout; long deadline = System.nanoTime() + nanos; boolean cancelled = false, interrupted = false; while (!canReacquire(node)) { if ((interrupted |= Thread.interrupted()) || (nanos = deadline - System.nanoTime()) <= 0L) { if (cancelled = (node.getAndUnsetStatus(COND) & COND) != 0) break; } else LockSupport.parkNanos(this, nanos); } node.clearStatus(); acquire(node, savedState, false, false, false, 0L); if (cancelled) { unlinkCancelledWaiters(node); if (interrupted) throw new InterruptedException(); } else if (interrupted) Thread.currentThread().interrupt(); long remaining = deadline - System.nanoTime(); return (remaining <= nanosTimeout) ? remaining : Long.MIN_VALUE; }
|
5.2.1.4. public final boolean await(long time, TimeUnit unit)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public final boolean await(long time, TimeUnit unit) throws InterruptedException { long nanosTimeout = unit.toNanos(time); if (Thread.interrupted()) throw new InterruptedException(); ConditionNode node = new ConditionNode(); int savedState = enableWait(node); long nanos = (nanosTimeout < 0L) ? 0L : nanosTimeout; long deadline = System.nanoTime() + nanos; boolean cancelled = false, interrupted = false; while (!canReacquire(node)) { if ((interrupted |= Thread.interrupted()) || (nanos = deadline - System.nanoTime()) <= 0L) { if (cancelled = (node.getAndUnsetStatus(COND) & COND) != 0) break; } else LockSupport.parkNanos(this, nanos); } node.clearStatus(); acquire(node, savedState, false, false, false, 0L); if (cancelled) { unlinkCancelledWaiters(node); if (interrupted) throw new InterruptedException(); } else if (interrupted) Thread.currentThread().interrupt(); return !cancelled; }
|
5.2.1.5. public final boolean awaitUntil(Date deadline)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public final boolean awaitUntil(Date deadline) throws InterruptedException { long abstime = deadline.getTime(); if (Thread.interrupted()) throw new InterruptedException(); ConditionNode node = new ConditionNode(); int savedState = enableWait(node); boolean cancelled = false, interrupted = false; while (!canReacquire(node)) { if ((interrupted |= Thread.interrupted()) || System.currentTimeMillis() >= abstime) { if (cancelled = (node.getAndUnsetStatus(COND) & COND) != 0) break; } else LockSupport.parkUntil(this, abstime); } node.clearStatus(); acquire(node, savedState, false, false, false, 0L); if (cancelled) { unlinkCancelledWaiters(node); if (interrupted) throw new InterruptedException(); } else if (interrupted) Thread.currentThread().interrupt(); return !cancelled; }
|
5.2.1.6. public final void signal()
1 2 3 4 5 6 7
| public final void signal() { ConditionNode first = firstWaiter; if (!isHeldExclusively()) throw new IllegalMonitorStateException(); if (first != null) doSignal(first, false); }
|
5.2.1.7. public final void signalAll()
1 2 3 4 5 6 7
| public final void signalAll() { ConditionNode first = firstWaiter; if (!isHeldExclusively()) throw new IllegalMonitorStateException(); if (first != null) doSignal(first, true); }
|