JDK 8 Condition 源码详解(详细注释版)

JDK 8 Condition 源码详解(详细注释版)

1. 类定义和基本属性

public class ConditionObject implements Condition, java.io.Serializable {
    
    // 序列化版本号
    private static final long serialVersionUID = 1173984872572414699L;

    /**
     * 条件等待队列的第一个节点
     * 构成一个FIFO的单向链表队列
     */
    private transient Node firstWaiter;

    /**
     * 条件等待队列的最后一个节点
     */
    private transient Node lastWaiter;

    /**
     * Node类继承自AbstractQueuedSynchronizer.Node
     * 用于构建条件等待队列
     * 在条件队列中,Node的nextWaiter字段指向下一个等待节点
     */
    public class Node {
        // 节点状态常量
        static final int CANCELLED =  1;  // 节点已取消
        static final int SIGNAL    = -1;  // 节点需要被唤醒
        static final int CONDITION = -2;  // 节点在条件队列中等待
        static final int PROPAGATE = -3;  // 传播(共享模式下使用)

        volatile int waitStatus;     // 节点状态
        volatile Node prev;          // 前驱节点(同步队列中使用)
        volatile Node next;          // 后继节点(同步队列中使用)
        volatile Thread thread;      // 节点关联的线程
        Node nextWaiter;             // 指向条件队列中的下一个节点

        // 构造方法
        Node(Thread thread, Node mode) {
            this.nextWaiter = mode;
            this.thread = thread;
        }

        Node() {} // 用于建立头节点和哨兵节点
    }

    /**
     * ConditionObject的构造方法
     * 通常由AbstractQueuedSynchronizer的newCondition()方法创建
     */
    public ConditionObject() { }

2. 核心等待方法(详细注释)

    /**
     * 使当前线程在条件上等待
     * 当前线程必须持有与Condition关联的锁
     * 
     * 等待过程:
     * 1. 释放锁(通过AQS的release方法)
     * 2. 将当前线程加入条件等待队列
     * 3. 阻塞当前线程
     * 4. 被唤醒后重新获取锁
     * 
     * 注意事项:
     * - 必须在获取锁的情况下调用
     * - 会释放锁并在被唤醒后重新获取锁
     * - 不响应中断,如果线程被中断会记录中断状态
     * 
     * @throws IllegalMonitorStateException 如果没有持有锁
     */
    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();
    }

    /**
     * 使当前线程在条件上等待
     * 这是Condition接口的核心方法
     * 
     * 等待过程:
     * 1. 释放锁
     * 2. 加入条件等待队列
     * 3. 阻塞线程
     * 4. 被唤醒后重新获取锁
     * 
     * 中断处理:
     * - 如果线程在等待过程中被中断,会抛出InterruptedException
     * - 线程可以被优雅地中止
     * 
     * @throws InterruptedException 如果线程被中断
     * @throws IllegalMonitorStateException 如果没有持有锁
     */
    public final void await() throws InterruptedException {
        // 检查线程是否被中断
        if (Thread.interrupted())
            throw new InterruptedException();
        
        // 将当前线程加入条件等待队列
        Node node = addConditionWaiter();
        // 完全释放锁
        int savedState = fullyRelease(node);
        int interruptMode = 0;
        // 循环等待直到被转移到同步队列
        while (!isOnSyncQueue(node)) {
            // 阻塞当前线程
            LockSupport.park(this);
            // 检查中断模式
            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);
    }

    /**
     * 使当前线程在条件上等待指定时间
     * 
     * 等待过程:
     * 1. 释放锁
     * 2. 加入条件等待队列
     * 3. 阻塞线程或超时返回
     * 4. 被唤醒或超时后重新获取锁
     * 
     * 超时处理:
     * - 在指定时间内未被唤醒,返回false
     * - 被提前唤醒,返回true
     * - 等待过程中可被中断
     * 
     * @param time 等待时间
     * @param unit 时间单位
     * @return 如果被唤醒返回true,如果超时返回false
     * @throws InterruptedException 如果线程被中断
     * @throws IllegalMonitorStateException 如果没有持有锁
     */
    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;
    }

    /**
     * 使当前线程在条件上等待到指定时间点
     * 
     * 等待过程:
     * 1. 释放锁
     * 2. 加入条件等待队列
     * 3. 阻塞线程或到达指定时间
     * 4. 被唤醒或超时后重新获取锁
     * 
     * 时间点处理:
     * - 在指定时间点前被唤醒,返回false
     * - 到达指定时间点仍未被唤醒,返回true
     * - 等待过程中可被中断
     * 
     * @param deadline 绝对时间点(纳秒)
     * @return 如果超时返回true,如果被提前唤醒返回false
     * @throws InterruptedException 如果线程被中断
     * @throws IllegalMonitorStateException 如果没有持有锁
     */
    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;
    }

    /**
     * 使当前线程在条件上等待指定纳秒数
     * 
     * @param nanosTimeout 等待纳秒数
     * @return 如果被唤醒返回剩余纳秒数,如果超时返回小于等于0的值
     * @throws InterruptedException 如果线程被中断
     * @throws IllegalMonitorStateException 如果没有持有锁
     */
    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 nanosTimeout;
    }

3. 核心唤醒方法(详细注释)

    /**
     * 唤醒一个等待在条件上的线程
     * 
     * 唤醒过程:
     * 1. 从条件等待队列中移除第一个节点
     * 2. 将该节点转移到同步队列
     * 3. 该线程将在下次调度时尝试获取锁
     * 
     * 注意事项:
     * - 唤醒的线程不会立即恢复执行
     * - 唤醒的线程需要重新竞争锁
     * - 必须在持有锁的情况下调用
     * 
     * @throws IllegalMonitorStateException 如果没有持有锁
     */
    public final void signal() {
        // 检查当前线程是否持有锁
        if (!isHeldExclusively())
            throw new IllegalMonitorStateException();
        Node first = firstWaiter;
        if (first != null)
            doSignal(first); // 唤醒第一个等待者
    }

    /**
     * 唤醒所有等待在条件上的线程
     * 
     * 唤醒过程:
     * 1. 从条件等待队列中移除所有节点
     * 2. 将所有节点转移到同步队列
     * 3. 所有线程将在下次调度时尝试获取锁
     * 
     * 使用场景:
     * - 条件发生根本性变化
     * - 需要唤醒所有等待线程
     * - 批量操作完成后的通知
     * 
     * @throws IllegalMonitorStateException 如果没有持有锁
     */
    public final void signalAll() {
        // 检查当前线程是否持有锁
        if (!isHeldExclusively())
            throw new IllegalMonitorStateException();
        Node first = firstWaiter;
        if (first != null)
            doSignalAll(first); // 唤醒所有等待者
    }

    /**
     * 实际的单个唤醒操作
     * @param first 第一个等待节点
     */
    private void doSignal(Node first) {
        do {
            if ( (firstWaiter = first.nextWaiter) == null)
                lastWaiter = null;
            first.nextWaiter = null;
        } while (!transferForSignal(first) &&
                 (first = firstWaiter) != null);
    }

    /**
     * 实际的全部唤醒操作
     * @param first 第一个等待节点
     */
    private void doSignalAll(Node first) {
        lastWaiter = firstWaiter = null;
        do {
            Node next = first.nextWaiter;
            first.nextWaiter = null;
            transferForSignal(first);
            first = next;
        } while (first != null);
    }

    /**
     * 将节点从条件队列转移到同步队列
     * @param node 要转移的节点
     * @return 如果转移成功返回true,否则返回false
     */
    final boolean transferForSignal(Node node) {
        // 如果节点已被取消,转移失败
        if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
            return false;

        // 将节点加入同步队列
        Node p = enq(node);
        int ws = p.waitStatus;
        // 如果前驱节点状态不正确,直接唤醒节点
        if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
            LockSupport.unpark(node.thread);
        return true;
    }

4. 辅助方法(详细注释)

    /**
     * 将当前线程加入条件等待队列
     * @return 新创建的节点
     */
    private Node addConditionWaiter() {
        Node t = lastWaiter;
        // 如果尾节点状态不正确,清理取消的节点
        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;
    }

    /**
     * 完全释放锁
     * 对于可重入锁,会释放所有重入次数
     * @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;
        }
    }

    /**
     * 检查节点是否在同步队列中
     * @param node 节点
     * @return 如果在同步队列中返回true,否则返回false
     */
    final boolean isOnSyncQueue(Node node) {
        if (node.waitStatus == Node.CONDITION || node.prev == null)
            return false;
        if (node.next != null) // If has successor, it must be on queue
            return true;
        // 从尾部向前查找
        return findNodeFromTail(node);
    }

    /**
     * 从尾部开始查找节点
     * @param node 要查找的节点
     * @return 如果找到返回true,否则返回false
     */
    private boolean findNodeFromTail(Node node) {
        Node t = tail;
        for (;;) {
            if (t == node)
                return true;
            if (t == null)
                return false;
            t = t.prev;
        }
    }

    /**
     * 清理取消的等待者
     * 移除条件队列中状态不正确的节点
     */
    private void unlinkCancelledWaiters() {
        Node t = firstWaiter;
        Node trail = null;
        while (t != null) {
            Node next = t.nextWaiter;
            if (t.waitStatus != Node.CONDITION) {
                t.nextWaiter = null;
                if (trail == null)
                    firstWaiter = next;
                else
                    trail.nextWaiter = next;
                if (next == null)
                    lastWaiter = trail;
            }
            else
                trail = t;
            t = next;
        }
    }

    /**
     * 检查等待期间的中断
     * @param node 节点
     * @return 中断模式
     */
    private int checkInterruptWhileWaiting(Node node) {
        return Thread.interrupted() ?
            (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
            0;
    }

    /**
     * 处理取消等待后的转移
     * @param node 节点
     * @return 如果转移成功返回true,否则返回false
     */
    final boolean transferAfterCancelledWait(Node node) {
        if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
            enq(node);
            return true;
        }
        // 等待转移完成
        while (!isOnSyncQueue(node))
            Thread.yield();
        return false;
    }

    /**
     * 等待后报告中断
     * @param interruptMode 中断模式
     * @throws InterruptedException 如果是抛出异常模式
     */
    private void reportInterruptAfterWait(int interruptMode)
        throws InterruptedException {
        if (interruptMode == THROW_IE)
            throw new InterruptedException();
        else if (interruptMode == REINTERRUPT)
            selfInterrupt();
    }

    // 中断模式常量
    private static final int REINTERRUPT =  1; // 重新中断
    private static final int THROW_IE    =  2; // 抛出中断异常
    private static final long spinForTimeoutThreshold = 1000L; // 自旋超时阈值

5. 查询方法(详细注释)

    /**
     * 查询是否有线程在等待此条件
     * 
     * 查询结果:
     * - true:有线程在条件等待队列中
     * - false:没有线程在等待
     * 
     * 注意事项:
     * - 这是一个瞬时状态查询
     * - 返回值可能很快过时
     * - 主要用于监控和调试
     * 
     * @return 如果有等待线程返回true,否则返回false
     */
    public 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;
    }

    /**
     * 获取等待此条件的线程数量
     * 
     * 查询结果:
     * - 返回条件等待队列中的线程数量
     * - 这是一个估算值,因为线程状态可能随时变化
     * 
     * 使用场景:
     * - 监控条件的使用情况
     * - 实现负载监控
     * - 性能调优
     * 
     * @return 等待线程数量
     */
    public 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;
    }

    /**
     * 获取等待此条件的线程集合
     * 
     * 查询结果:
     * - 返回条件等待队列中线程的集合
     * - 集合是线程安全的快照
     * - 不包含已取消的线程
     * 
     * 使用场景:
     * - 调试和诊断
     * - 实现管理工具
     * - 分析系统状态
     * 
     * @return 等待线程集合
     */
    protected final Collection<Thread> getWaitingThreads() {
        if (!isHeldExclusively())
            throw new IllegalMonitorStateException();
        ArrayList<Thread> list = new ArrayList<Thread>();
        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;
    }

6. Condition 的特点分析

核心设计理念:

/**
 * Condition的核心设计思想:
 * 
 * 1. 与Lock的绑定关系:
 *    - Condition必须与特定的Lock实例绑定
 *    - 每个Lock可以创建多个Condition
 *    - 提供比内置监视器更灵活的线程等待/通知机制
 * 
 * 2. 条件队列机制:
 *    - 每个Condition维护独立的等待队列
 *    - 支持精确的通知控制(signal vs signalAll)
 *    - 与AQS的同步队列分离
 * 
 * 3. 灵活的等待方式:
 *    - 支持无限期等待(await)
 *    - 支持可中断等待(await)
 *    - 支持超时等待(awaitNanos, awaitUntil)
 *    - 支持不中断等待(awaitUninterruptibly)
 * 
 * 4. 高效的通知机制:
 *    - signal()唤醒单个线程
 *    - signalAll()唤醒所有线程
 *    - 精确控制唤醒范围
 *    - 避免不必要的线程唤醒
 * 
 * 5. 状态管理:
 *    - 自动管理线程的阻塞和唤醒
 *    - 维护等待队列的一致性
 *    - 处理中断和超时情况
 * 
 * 6. 与内置监视器的对比:
 *    - 一个对象一个监视器 vs 一个Lock多个Condition
 *    - notify/notifyAll vs signal/signalAll
 *    - synchronized块 vs Lock/Condition组合
 *    - 更灵活的使用方式
 * 
 * 适用场景:
 * - 需要多个等待条件的场景
 * - 需要精确控制线程唤醒的场景
 * - 需要比内置监视器更灵活的同步机制
 * - 实现生产者-消费者模式
 * - 实现复杂的线程协调逻辑
 */

性能特征分析:

/**
 * Condition的性能特征:
 * 
 * 等待时间复杂度:
 * - await():O(1) 加入队列,O(1) 阻塞
 * - signal():O(1) 移除队列,O(1) 转移到同步队列
 * - signalAll():O(n) 移除所有队列节点
 * 
 * 内存复杂度:
 * - O(1) 基本状态开销
 * - O(n) 等待队列开销(n为等待线程数)
 * - O(1) 每个Condition实例开销
 * 
 * 并发特性:
 * - 完全线程安全
 * - 与Lock的互操作性保证
 * - 支持高并发环境
 * - 无锁设计(通过AQS)
 * 
 * 与内置监视器对比:
 * - 灵活性:Condition > synchronized
 * - 性能:Condition ≥ synchronized(JDK 1.6后)
 * - 功能:Condition > synchronized
 * - 易用性:synchronized > Condition
 * 
 * 内存使用:
 *    - 每个等待线程占用一个Node对象
 *    - 及时GC,避免内存泄漏
 *    - 条件队列节点在唤醒后被清理
 * 
 * 适用性:
 *    - 复杂同步逻辑:Condition更优
 *    - 简单同步需求:synchronized更优
 *    - 多条件等待:Condition必需
 *    - 精确唤醒控制:Condition更优
 */

7. 使用示例和最佳实践

/**
 * 使用示例:
 * 
 * // 基本使用(生产者-消费者模式)
 * class BoundedBuffer {
 *     final Lock lock = new ReentrantLock();
 *     final Condition notFull = lock.newCondition();  // 缓冲区不满条件
 *     final Condition notEmpty = lock.newCondition(); // 缓冲区不空条件
 *     
 *     final Object[] items = new Object[100];
 *     int putptr, takeptr, count;
 *     
 *     // 生产者方法
 *     public void put(Object x) throws InterruptedException {
 *         lock.lock();
 *         try {
 *             // 等待缓冲区不满
 *             while (count == items.length)
 *                 notFull.await(); // 等待空间
 *             
 *             items[putptr] = x;
 *             if (++putptr == items.length) putptr = 0;
 *             ++count;
 *             
 *             notEmpty.signal(); // 通知消费者有数据
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 *     
 *     // 消费者方法
 *     public Object take() throws InterruptedException {
 *         lock.lock();
 *         try {
 *             // 等待缓冲区不空
 *             while (count == 0)
 *                 notEmpty.await(); // 等待数据
 *             
 *             Object x = items[takeptr];
 *             if (++takeptr == items.length) takeptr = 0;
 *             --count;
 *             
 *             notFull.signal(); // 通知生产者有空间
 *             return x;
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 * }
 * 
 * // 多条件等待示例
 * class ConditionExample {
 *     private final Lock lock = new ReentrantLock();
 *     private final Condition conditionA = lock.newCondition();
 *     private final Condition conditionB = lock.newCondition();
 *     private final Condition conditionC = lock.newCondition();
 *     
 *     private boolean flagA = false;
 *     private boolean flagB = false;
 *     private boolean flagC = false;
 *     
 *     // 等待条件A满足
 *     public void waitForConditionA() throws InterruptedException {
 *         lock.lock();
 *         try {
 *             while (!flagA) {
 *                 conditionA.await();
 *             }
 *             // 条件A满足后的处理
 *             System.out.println("Condition A is satisfied");
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 *     
 *     // 等待条件B满足
 *     public void waitForConditionB() throws InterruptedException {
 *         lock.lock();
 *         try {
 *             while (!flagB) {
 *                 conditionB.await();
 *             }
 *             // 条件B满足后的处理
 *             System.out.println("Condition B is satisfied");
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 *     
 *     // 设置条件A并通知等待者
 *     public void setConditionA() {
 *         lock.lock();
 *         try {
 *             flagA = true;
 *             conditionA.signalAll(); // 唤醒所有等待条件A的线程
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 *     
 *     // 设置条件B并通知等待者
 *     public void setConditionB() {
 *         lock.lock();
 *         try {
 *             flagB = true;
 *             conditionB.signal(); // 只唤醒一个等待条件B的线程
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 * }
 * 
 * // 超时等待示例
 * class TimeoutExample {
 *     private final Lock lock = new ReentrantLock();
 *     private final Condition condition = lock.newCondition();
 *     private boolean ready = false;
 *     
 *     // 带超时的等待
 *     public boolean waitForReady(long timeout, TimeUnit unit) 
 *             throws InterruptedException {
 *         lock.lock();
 *         try {
 *             long nanos = unit.toNanos(timeout);
 *             while (!ready && nanos > 0) {
 *                 nanos = condition.awaitNanos(nanos);
 *             }
 *             return ready;
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 *     
 *     // 带绝对时间的等待
 *     public boolean waitForReadyUntil(Date deadline) 
 *             throws InterruptedException {
 *         lock.lock();
 *         try {
 *             while (!ready) {
 *                 if (condition.awaitUntil(deadline)) {
 *                     // 被唤醒
 *                     if (!ready) continue;
 *                     else break;
 *                 } else {
 *                     // 超时
 *                     return false;
 *                 }
 *             }
 *             return true;
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 *     
 *     // 设置准备状态并通知
 *     public void setReady() {
 *         lock.lock();
 *         try {
 *             ready = true;
 *             condition.signalAll();
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 * }
 * 
 * // 不可中断等待示例
 * class UninterruptibleExample {
 *     private final Lock lock = new ReentrantLock();
 *     private final Condition condition = lock.newCondition();
 *     private boolean ready = false;
 *     
 *     // 不可中断的等待
 *     public void waitForReadyUninterruptibly() {
 *         lock.lock();
 *         try {
 *             while (!ready) {
 *                 condition.awaitUninterruptibly();
 *             }
 *             // 处理准备好的情况
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 *     
 *     // 设置准备状态并通知
 *     public void setReady() {
 *         lock.lock();
 *         try {
 *             ready = true;
 *             condition.signalAll();
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 * }
 * 
 * 最佳实践:
 * 
 * 1. 正确的锁获取和释放:
 *    Lock lock = new ReentrantLock();
 *    Condition condition = lock.newCondition();
 *    
 *    // 等待条件
 *    lock.lock();
 *    try {
 *         while (!conditionMet()) { // 必须使用while循环
 *             condition.await();
 *         }
 *         // 条件满足后的处理
 *    } finally {
 *         lock.unlock(); // 必须在finally块中释放锁
 *    }
 *    
 *    // 通知等待者
 *    lock.lock();
 *    try {
 *         setConditionMet(true);
 *         condition.signal(); // 或者 condition.signalAll();
 *    } finally {
 *         lock.unlock();
 *    }
 * 
 * 2. 使用while循环检查条件:
 *    // 错误的做法:使用if语句
 *    lock.lock();
 *    try {
 *        if (!conditionMet()) { // 危险!虚假唤醒可能导致问题
 *            condition.await();
 *        }
 *        // 处理逻辑
 *    } finally {
 *        lock.unlock();
 *    }
 *    
 *    // 正确的做法:使用while循环
 *    lock.lock();
 *    try {
 *        while (!conditionMet()) { // 正确处理虚假唤醒
 *            condition.await();
 *        }
 *        // 处理逻辑
 *    } finally {
 *        lock.unlock();
 *    }
 * 
 * 3. 选择合适的唤醒方法:
 *    Lock lock = new ReentrantLock();
 *    Condition condition = lock.newCondition();
 *    
 *    // 当只有一个线程需要被唤醒时使用signal()
 *    public void singleNotification() {
 *        lock.lock();
 *        try {
 *            // 状态改变
 *            updateState();
 *            condition.signal(); // 唤醒一个等待者
 *        } finally {
 *            lock.unlock();
 *        }
 *    }
 *    
 *    // 当所有线程都需要被唤醒时使用signalAll()
 *    public void broadcastNotification() {
 *        lock.lock();
 *        try {
 *            // 状态发生根本性改变
 *            updateState();
 *            condition.signalAll(); // 唤醒所有等待者
 *        } finally {
 *            lock.unlock();
 *        }
 *    }
 * 
 * 4. 处理中断异常:
 *    Lock lock = new ReentrantLock();
 *    Condition condition = lock.newCondition();
 *    
 *    public void interruptibleWait() throws InterruptedException {
 *        lock.lock();
 *        try {
 *            while (!conditionMet()) {
 *                condition.await(); // 可能抛出InterruptedException
 *            }
 *            // 处理逻辑
 *        } finally {
 *            lock.unlock();
 *        }
 *    }
 *    
 *    // 调用方处理中断
 *    try {
 *        interruptibleWait();
 *    } catch (InterruptedException e) {
 *        Thread.currentThread().interrupt(); // 恢复中断状态
 *        // 处理中断情况
 *    }
 * 
 * 5. 设置合理的超时时间:
 *    Lock lock = new ReentrantLock();
 *    Condition condition = lock.newCondition();
 *    
 *    public boolean waitForCondition(long timeout, TimeUnit unit) 
 *            throws InterruptedException {
 *        lock.lock();
 *        try {
 *            long nanos = unit.toNanos(timeout);
 *            while (!conditionMet() && nanos > 0) {
 *                nanos = condition.awaitNanos(nanos);
 *            }
 *            return conditionMet();
 *        } finally {
 *            lock.unlock();
 *        }
 *    }
 *    
 *    // 使用示例
 *    try {
 *        if (waitForCondition(5, TimeUnit.SECONDS)) {
 *            System.out.println("Condition satisfied within timeout");
 *        } else {
 *            System.out.println("Timeout occurred");
 *        }
 *    } catch (InterruptedException e) {
 *        Thread.currentThread().interrupt();
 *    }
 * 
 * 6. 使用不可中断等待:
 *    Lock lock = new ReentrantLock();
 *    Condition condition = lock.newCondition();
 *    
 *    public void uninterruptibleWait() {
 *        lock.lock();
 *        try {
 *            while (!conditionMet()) {
 *                condition.awaitUninterruptibly(); // 不会抛出中断异常
 *            }
 *            // 处理逻辑
 *        } finally {
 *            lock.unlock();
 *        }
 *    }
 * 
 * 7. 监控Condition的使用情况:
 *    Lock lock = new ReentrantLock();
 *    Condition condition = lock.newCondition();
 *    
 *    // 检查是否有线程在等待
 *    if (condition.hasWaiters()) {
 *        System.out.println("There are threads waiting on this condition");
 *        System.out.println("Number of waiting threads: " + 
 *                          condition.getWaitQueueLength());
 *    }
 *    
 *    // 获取等待线程列表
 *    Collection<Thread> waitingThreads = condition.getWaitingThreads();
 *    for (Thread thread : waitingThreads) {
 *        System.out.println("Waiting thread: " + thread.getName());
 *    }
 * 
 * 8. 多条件管理:
 *    class MultiConditionExample {
 *        private final Lock lock = new ReentrantLock();
 *        private final Condition readCondition = lock.newCondition();
 *        private final Condition writeCondition = lock.newCondition();
 *        private final Condition errorCondition = lock.newCondition();
 *        
 *        private volatile boolean readable = false;
 *        private volatile boolean writable = false;
 *        private volatile boolean errorOccurred = false;
 *        
 *        public void waitForRead() throws InterruptedException {
 *            lock.lock();
 *            try {
 *                while (!readable && !errorOccurred) {
 *                    readCondition.await();
 *                }
 *                if (errorOccurred) {
 *                    throw new RuntimeException("Error occurred while waiting");
 *                }
 *            } finally {
 *                lock.unlock();
 *            }
 *        }
 *        
 *        public void waitForWrite() throws InterruptedException {
 *            lock.lock();
 *            try {
 *                while (!writable && !errorOccurred) {
 *                    writeCondition.await();
 *                }
 *                if (errorOccurred) {
 *                    throw new RuntimeException("Error occurred while waiting");
 *                }
 *            } finally {
 *                lock.unlock();
 *            }
 *        }
 *        
 *        public void signalReadReady() {
 *            lock.lock();
 *            try {
 *                readable = true;
 *                readCondition.signalAll();
 *            } finally {
 *                lock.unlock();
 *            }
 *        }
 *        
 *        public void signalWriteReady() {
 *            lock.lock();
 *            try {
 *                writable = true;
 *                writeCondition.signalAll();
 *            } finally {
 *                lock.unlock();
 *            }
 *        }
 *        
 *        public void signalError() {
 *            lock.lock();
 *            try {
 *                errorOccurred = true;
 *                readCondition.signalAll();
 *                writeCondition.signalAll();
 *                errorCondition.signalAll();
 *            } finally {
 *                lock.unlock();
 *            }
 *        }
 *    }
 * 
 * 9. 避免死锁:
 *    // 确保锁的获取顺序一致
 *    Lock lock1 = new ReentrantLock();
 *    Lock lock2 = new ReentrantLock();
 *    Condition condition1 = lock1.newCondition();
 *    Condition condition2 = lock2.newCondition();
 *    
 *    // 正确的做法:保持一致的锁获取顺序
 *    public void method1() {
 *        lock1.lock();
 *        try {
 *            lock2.lock();
 *            try {
 *                // 业务逻辑
 *            } finally {
 *                lock2.unlock();
 *            }
 *        } finally {
 *            lock1.unlock();
 *        }
 *    }
 *    
 *    public void method2() {
 *        lock1.lock(); // 保持相同的获取顺序
 *        try {
 *            lock2.lock();
 *            try {
 *                // 业务逻辑
 *            } finally {
 *                lock2.unlock();
 *            }
 *        } finally {
 *            lock1.unlock();
 *        }
 *    }
 * 
 * 10. 性能调优:
 *    // 在高并发场景下监控性能
 *    Lock lock = new ReentrantLock();
 *    Condition condition = lock.newCondition();
 *    
 *    // 定期检查Condition的使用情况
 *    if (condition.getWaitQueueLength() > 100) {
 *        System.out.println("High contention detected on condition");
 *        // 可能需要优化同步逻辑
 *    }
 *    
 *    // 使用条件变量减少不必要的唤醒
 *    public void optimizedNotification() {
 *        lock.lock();
 *        try {
 *            // 只在必要时发送通知
 *            if (needToNotify()) {
 *                updateState();
 *                condition.signal(); // 精确通知
 *            }
 *        } finally {
 *            lock.unlock();
 *        }
 *    }
 */

8. 与其他同步机制的比较

/**
 * Condition vs Object's wait/notify vs CountDownLatch vs Semaphore:
 * 
 * Condition:
 * - 与特定Lock绑定
 * - 支持多个等待条件
 * - 精确的唤醒控制
 * - 支持超时和中断
 * - 灵活的使用方式
 * 
 * Object's wait/notify:
 * - 与对象监视器绑定
 * - 一个对象一个等待队列
 * - notify/notifyAll唤醒
 * - synchronized关键字使用
 * - 功能相对简单
 * 
 * CountDownLatch:
 * - 一次性同步工具
 * - 倒计数机制
 * - 不支持重置
 * - 适用于等待多个事件完成
 * 
 * Semaphore:
 * - 计数信号量
 * - 控制资源访问数量
 * - 支持公平性和非公平性
 * - 适用于资源池管理
 * 
 * 选择建议:
 * - 复杂同步逻辑:Condition
 * - 简单等待/通知:Object's wait/notify
 * - 等待事件完成:CountDownLatch
 * - 资源访问控制:Semaphore
 * - 生产者-消费者:Condition或BlockingQueue
 * 
 * 性能对比:
 * - 简单场景:Object's wait/notify ≈ Condition
 * - 复杂场景:Condition > Object's wait/notify
 * - 一次性同步:CountDownLatch最优
 * - 资源控制:Semaphore最优
 * 
 * 功能对比:
 * - 多条件支持:Condition独有
 * - 精确唤醒:Condition > Object's wait/notify
 * - 超时控制:Condition ≥ Object's wait/notify
 * - 中断支持:Condition ≥ Object's wait/notify
 * - 易用性:Object's wait/notify > Condition
 */

9. 总结

Condition 的核心特性:

  1. 与Lock的绑定关系

    • 必须与特定的Lock实例绑定
    • 每个Lock可以创建多个Condition
    • 提供比内置监视器更灵活的机制
  2. 条件队列机制

    • 每个Condition维护独立的等待队列
    • 支持精确的通知控制
    • 与AQS的同步队列分离
  3. 灵活的等待方式

    • 支持无限期、可中断、超时、不可中断等待
    • 提供多种等待方法满足不同需求
    • 自动处理线程阻塞和唤醒
  4. 高效的唤醒机制

    • signal()精确唤醒单个线程
    • signalAll()唤醒所有等待线程
    • 避免不必要的线程唤醒
  5. 丰富的查询API

    • 提供详细的等待状态信息
    • 支持监控和诊断
    • 便于调试和性能调优
  6. 线程安全

    • 所有操作都是线程安全的
    • 与Lock的互操作性保证
    • 支持高并发环境

适用场景:

  • 需要多个等待条件的复杂同步场景
  • 需要精确控制线程唤醒的场景
  • 生产者-消费者模式的实现
  • 实现复杂的线程协调逻辑
  • 需要比内置监视器更灵活的同步机制

注意事项:

  • 必须在获取锁的情况下调用await/signal方法
  • 等待条件时必须使用while循环检查
  • 正确处理中断异常
  • 合理选择signal和signalAll方法
  • 在finally块中释放锁
  • 避免死锁和竞态条件

性能优化建议:

  1. 根据业务需求选择合适的等待方式
  2. 合理使用超时控制避免无限等待
  3. 选择合适的唤醒方法减少不必要唤醒
  4. 监控Condition的使用情况
  5. 优化条件检查逻辑减少虚假唤醒
  6. 保持一致的锁获取顺序避免死锁
  7. 定期分析和调优同步逻辑
  8. 使用条件变量减少不必要的通知
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值