threading.Condition() 中wait()和notify()的一个区别

本文详细解析了Java并发编程中wait()与notify()方法的运作机制。wait()方法在调用时会释放对象锁,而notify()则在等待下一个wait()或代码块结束时释放锁。notify()若无相应wait()配对,则视为无效。

wait()会直接释放锁,而notify()要等到下个wait()(或者是代码块结束,没测试,但八九不离十感觉)出现时才释放锁。
同时notify()如果没有对应wait()相当于没写代码。

`threading.Condition` 是 Python 中用于线程同步的高级机制,它结合了锁(`Lock` 或 `RLock`)等待/通知功能,允许线程在某个条件不满足时主动等待,并在条件可能满足时被其他线程通知唤醒。它比简单的锁(`Lock`)更灵活,适用于复杂的线程间协调场景。 --- ### **核心功能** 1. **等待(`wait()`)** - 线程调用 `wait()` 时会释放底层锁并阻塞,直到其他线程调用 `notify()` 或 `notify_all()`。 - 被唤醒后,线程会重新获取锁并继续执行。 2. **通知(`notify()` / `notify_all()`)** - `notify(n=1)`:唤醒最多 `n` 个等待线程。 - `notify_all()`:唤醒所有等待线程。 3. **关联锁** - `Condition` 必须与一个锁(`Lock` 或 `RLock`)绑定,默认会创建 `RLock`。 --- ### **基本用法** ```python import threading # 共享资源 shared_data = [] condition = threading.Condition() def producer(): with condition: shared_data.append("data") condition.notify() # 通知消费者 def consumer(): with condition: while not shared_data: condition.wait() # 等待数据 print("Consumed:", shared_data.pop()) # 启动线程 t1 = threading.Thread(target=producer) t2 = threading.Thread(target=consumer) t2.start() t1.start() ``` --- ### **关键点** 1. **`with` 语句自动管理锁** - 使用 `with condition` 会自动获取释放底层锁,避免死锁。 2. **`wait()` 必须在循环中调用** - 防止虚假唤醒(spurious wakeups),通常结合 `while` 检查条件: ```python while not condition_met: condition.wait() ``` 3. **与 `Lock` 的区别** - `Lock` 仅控制对共享资源的访问,而 `Condition` 允许线程基于条件等待/唤醒。 --- ### **典型应用场景** 1. **生产者-消费者模型** - 生产者通知消费者数据已就绪。 2. **任务队列** - 线程等待队列非空时处理任务。 3. **资源池管理** - 线程等待资源释放后再获取。 --- ### **注意事项** 1. **通知丢失问题** - 如果通知(`notify()`)发出时没有线程在等待,该通知会丢失。需确保逻辑正确性。 2. **性能考虑** - 频繁唤醒线程可能导致竞争,必要时用 `notify_all()` 替代 `notify()`。 3. **避免死锁** - 确保在 `notify()` 后释放锁(`with` 语句可自动处理)。 --- ### **完整示例** ```python import threading import time class ThreadSafeQueue: def __init__(self): self.queue = [] self.condition = threading.Condition() def put(self, item): with self.condition: self.queue.append(item) self.condition.notify() # 通知消费者 def get(self): with self.condition: while not self.queue: self.condition.wait() # 等待数据 return self.queue.pop(0) # 使用队列 queue = ThreadSafeQueue() def worker(): print("Got:", queue.get()) t = threading.Thread(target=worker) t.start() time.sleep(1) # 模拟延迟 queue.put("Hello") # 生产数据 t.join() ``` --- ### **相关问题** 1. `Condition` 的 `wait()` 方法为什么建议在循环中调用? 2. `Condition` `Event` 在线程同步中有何区别? 3. 如何避免 `Condition` 中的虚假唤醒? 4. `notify()` `notify_all()` 的使用场景分别是什么? 5. 如果忘记在 `Condition` 中使用锁,会发生什么错误?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值