C产品如何满足特定用户需求?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1047个文字,预计阅读时间需要5分钟。
这是最常见的坑:
正确姿势是:先用 lock(obj) 或 Monitor.Enter 获取锁,再调用 Monitor.Wait;它内部会自动释放该锁,并在被 Pulse 或 PulseAll 唤醒后、重新竞争获取同一把锁——注意,不是立刻恢复执行,而是要再次抢到锁才能继续往下走。
- 错误示例:
Monitor.Wait(someObj)单独写在外面 → 立即崩溃 - 正确结构:
lock (someObj) { Monitor.Wait(someObj); } - 若用
Monitor.Enter手动加锁,必须配对try/finally+Monitor.Exit,否则异常时锁不释放
Monitor.Pulse 只唤醒一个等待线程,且只对“已进入 Wait 队列”的线程有效
Monitor.Pulse 不是广播,也不保证唤醒谁。它只从当前对象的 wait queue 中挑一个线程(通常是等待最久的那个)移到 ready queue,让其有机会重新竞争锁。关键点在于:“Pulse 之前没有 Wait” = 白脉冲,什么也不会发生。
典型误用是生产者先 Pulse、消费者后 Wait,结果消费者永远卡住。因为 Pulse 发生时没人等着,信号丢失了。
本文共计1047个文字,预计阅读时间需要5分钟。
这是最常见的坑:
正确姿势是:先用 lock(obj) 或 Monitor.Enter 获取锁,再调用 Monitor.Wait;它内部会自动释放该锁,并在被 Pulse 或 PulseAll 唤醒后、重新竞争获取同一把锁——注意,不是立刻恢复执行,而是要再次抢到锁才能继续往下走。
- 错误示例:
Monitor.Wait(someObj)单独写在外面 → 立即崩溃 - 正确结构:
lock (someObj) { Monitor.Wait(someObj); } - 若用
Monitor.Enter手动加锁,必须配对try/finally+Monitor.Exit,否则异常时锁不释放
Monitor.Pulse 只唤醒一个等待线程,且只对“已进入 Wait 队列”的线程有效
Monitor.Pulse 不是广播,也不保证唤醒谁。它只从当前对象的 wait queue 中挑一个线程(通常是等待最久的那个)移到 ready queue,让其有机会重新竞争锁。关键点在于:“Pulse 之前没有 Wait” = 白脉冲,什么也不会发生。
典型误用是生产者先 Pulse、消费者后 Wait,结果消费者永远卡住。因为 Pulse 发生时没人等着,信号丢失了。

