您好,登录后才能下订单哦!
# 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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。