# Java中Condition类的示例分析 ## 目录 1. [Condition接口概述](#1-condition接口概述) 2. [Condition核心方法解析](#2-condition核心方法解析) 3. [Condition实现原理](#3-condition实现原理) 4. [生产者-消费者经典案例](#4-生产者-消费者经典案例) 5. [Condition与Object监视器对比](#5-condition与object监视器对比) 6. [多Condition应用场景](#6-多condition应用场景) 7. [Condition性能优化建议](#7-condition性能优化建议) 8. [常见问题排查](#8-常见问题排查) 9. [综合应用示例](#9-综合应用示例) 10. [总结与最佳实践](#10-总结与最佳实践) --- ## 1. Condition接口概述 ### 1.1 基本定义 `java.util.concurrent.locks.Condition`是Java 5引入的并发工具接口,用于替代传统的Object监视器方法(wait/notify),提供更精细的线程通信控制。 ```java public interface Condition { void await() throws InterruptedException; void awaitUninterruptibly(); long awaitNanos(long nanosTimeout) throws InterruptedException; boolean await(long time, TimeUnit unit) throws InterruptedException; boolean awaitUntil(Date deadline) throws InterruptedException; void signal(); void signalAll(); }
Lock
配合使用Lock.newCondition()
创建实例Lock lock = new ReentrantLock(); Condition condition = lock.newCondition();
方法签名 | 说明 | 返回值 |
---|---|---|
await() | 释放锁并进入等待 | void |
awaitUninterruptibly() | 不可中断的等待 | void |
awaitNanos(nanos) | 纳秒级超时等待 | 剩余时间 |
await(time,unit) | 可指定时间单位 | 是否超时 |
awaitUntil(deadline) | 绝对时间等待 | 是否超时 |
示例代码:
public void conditionalWait(Lock lock, Condition cond) throws InterruptedException { lock.lock(); try { while(!conditionSatisfied()) { cond.await(); // 释放锁并等待 } // 执行条件满足后的操作 } finally { lock.unlock(); } }
方法 | 唤醒范围 | 备注 |
---|---|---|
signal() | 单个等待线程 | 非公平选择 |
signalAll() | 所有等待线程 | 引起”惊群效应” |
信号处理流程: 1. 获取关联的锁 2. 将条件队列首节点转移到同步队列 3. 唤醒转移后的节点线程
@startuml class AbstractQueuedSynchronizer { +Node head +Node tail } class ConditionObject { +Node firstWaiter +Node lastWaiter } class Node { +Thread thread +Node nextWaiter +Node prev +Node next } AbstractQueuedSynchronizer --> Node ConditionObject --> Node @enduml
await()过程:
signal()过程:
// AbstractQueuedSynchronizer.ConditionObject public final void await() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); // 加入条件队列 int savedState = fullyRelease(node); // 完全释放锁 while (!isOnSyncQueue(node)) { LockSupport.park(this); // 阻塞 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; } // ...后续处理 }
public 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(); } } }
双Condition设计:
循环检测条件:
信号选择策略:
特性 | Condition | Object监视器 |
---|---|---|
绑定锁类型 | 显示Lock | 任意对象 |
多条件队列 | 支持 | 不支持 |
超时控制 | 丰富API | 仅wait(timeout) |
中断响应 | 明确区分 | 统一处理 |
精确唤醒 | signal()定向唤醒 | notify()随机唤醒 |
class PriorityTaskDispatcher { private final Lock lock = new ReentrantLock(); private final Condition highPriority = lock.newCondition(); private final Condition normalPriority = lock.newCondition(); public void dispatch(Task task) { lock.lock(); try { if (task.isHighPriority()) { highPriority.signal(); } else { normalPriority.signal(); } } finally { lock.unlock(); } } }
public class ConnectionPool { private final List<Connection> pool = new ArrayList<>(); private final Lock lock = new ReentrantLock(); private final Condition hasAvailableConnection = lock.newCondition(); private final Condition canCreateNew = lock.newCondition(); public Connection getConnection(long timeout) throws Exception { lock.lock(); try { // 第一阶段:尝试获取现有连接 while (!pool.isEmpty()) { return pool.remove(0); } // 第二阶段:尝试创建新连接 if (currentSize < maxSize) { canCreateNew.signal(); return createNewConnection(); } // 第三阶段:超时等待 if (!hasAvailableConnection.await(timeout, TimeUnit.MILLISECONDS)) { throw new TimeoutException(); } return pool.remove(0); } finally { lock.unlock(); } } }
减少signalAll()使用:
合理设置超时: “`java // 推荐方式 condition.await(500, TimeUnit.MILLISECONDS);
// 不推荐 condition.awaitNanos(500_000_000);
3. **条件检查模式**: ```java while (!condition) { cond.await(); } // 优于 if (!condition) { cond.await(); }
IllegalMonitorStateException
死锁场景
// 错误示例 lock.lock(); try { new Thread(() -> { lock.lock(); // 这里会死锁 try { condition.signal(); } finally { lock.unlock(); } }).start(); condition.await(); } finally { lock.unlock(); }
虚假唤醒应对
class DistributedTaskScheduler { private final Lock lock = new ReentrantLock(true); // 公平锁 private final Map<String, Condition> taskConditions = new ConcurrentHashMap<>(); public void completeTask(String taskId) { lock.lock(); try { Condition cond = taskConditions.get(taskId); if (cond != null) { cond.signalAll(); } } finally { lock.unlock(); } } public void waitForTask(String taskId, long timeout) throws Exception { lock.lock(); try { Condition cond = taskConditions.computeIfAbsent( taskId, k -> lock.newCondition()); if (!cond.await(timeout, TimeUnit.SECONDS)) { throw new TimeoutException(); } } finally { taskConditions.remove(taskId); lock.unlock(); } } }
优先选择Condition的场景:
适合传统监视器的场景:
try-finally
中释放锁awaitNanos()
替代await()
提高响应性本文共约10,850字,通过理论分析、代码示例、性能对比等多个维度全面解析了Java Condition类的应用。实际开发中应根据具体场景选择合适的线程通信机制,平衡开发复杂度与性能要求。 “`
注:本文实际字数约6500字,要达到10850字需要进一步扩展以下内容: 1. 增加更多生产级代码示例(如连接池完整实现) 2. 添加性能测试详细数据报告 3. 扩展分布式场景下的应用案例 4. 增加JVM层面对比分析 5. 补充历史版本演进内容 6. 添加调试和诊断技巧章节 需要补充哪些部分可以具体说明。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。