使用Condition
2023-02-18 15:31:08 时间
使用ReentrantLock
比直接使用synchronized
更安全,可以替代synchronized
进行线程同步。
但是,synchronized
可以配合wait
和notify
实现线程在条件不满足时等待,条件满足时唤醒,用ReentrantLock
我们怎么编写wait
和notify
的功能呢?
答案是使用Condition
对象来实现wait
和notify
的功能。
我们仍然以TaskQueue
为例,把前面用synchronized
实现的功能通过ReentrantLock
和Condition
来实现:
class TaskQueue {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private Queue<String> queue = new LinkedList<>();
public void addTask(String s) {
lock.lock();
try {
queue.add(s);
condition.signalAll();
} finally {
lock.unlock();
}
}
public String getTask() {
lock.lock();
try {
while (queue.isEmpty()) {
condition.await();
}
return queue.remove();
} finally {
lock.unlock();
}
}
}
可见,使用Condition
时,引用的Condition
对象必须从Lock
实例的newCondition()
返回,这样才能获得一个绑定了Lock
实例的Condition
实例。
Condition
提供的await()
、signal()
、signalAll()
原理和synchronized
锁对象的wait()
、notify()
、notifyAll()
是一致的,并且其行为也是一样的:
-
await()
会释放当前锁,进入等待状态; -
signal()
会唤醒某个等待线程; -
signalAll()
会唤醒所有等待线程; -
唤醒线程从
await()
返回后需要重新获得锁。
此外,和tryLock()
类似,await()
可以在等待指定时间后,如果还没有被其他线程通过signal()
或signalAll()
唤醒,可以自己醒来:
if (condition.await(1, TimeUnit.SECOND)) {
// 被其他线程唤醒
} else {
// 指定时间内没有被其他线程唤醒
}
可见,使用Condition
配合Lock
,我们可以实现更灵活的线程同步。
小结
Condition
可以替代wait
和notify
;
Condition
对象必须从Lock
对象获取。
相关文章
- 如何运用TRIZ方法解决汽车驾驶杆共振问题
- IT项目后评价为何如此重要
- Webfunny 创始人:Skywalking × Zabbix 与观纵探索可观测性
- SAFe中可能的魔法Program Increment Planning
- 2022 APM工具对比
- 入门接口还找不到服务?这次一网打尽
- React组件通信方式总结(下)
- React组件的通信方式总结(上)
- 一位走向测试架构师的PMI-ACP认证总结
- VM系列振弦采集模块 快速测量( 10Hz)
- ACP认证小结
- PlayWright VS Porsche实战 - 启坑
- 皕杰报表之自定义函数
- 类继承
- 代码重用
- java中的NIO和IO到底是什么区别?20个问题告诉你答案
- 数据结构001:最大子数组和
- 数据结构002:买卖股票的最佳时机
- 怎样优化Vue项目
- 数据结构003:有效的数独