Monitor.PulseAll
通知队列中的所有等待线程。
Monitor.Pulse
通知等待队列中的线程。(下一个等待线程)
只有下一个线程(一个线程)可以获取锁。那么区别是什么呢?
我什么时候应该使用Pulse
vs PulseAll
?
Monitor.PulseAll
通知队列中的所有等待线程。
Monitor.Pulse
通知等待队列中的线程。(下一个等待线程)
只有下一个线程(一个线程)可以获取锁。那么区别是什么呢?
我什么时候应该使用Pulse
vs PulseAll
?
当您想唤醒多个线程时使用PulseAll
,因为它们正在等待的条件现在可能满足多个线程。(等待几乎总是与条件相关联——您通常应该在while
循环中测试该条件。)
当您只想唤醒一个线程时使用Pulse
,因为实际上只有一个线程能够做有用的工作。
举两个比喻:
想象一下,您只有一台打印机。一次只有一个人可以使用它,所以如果你有很多人在等待,你可以让他们都进入睡眠状态——但是当打印机空闲时你只会唤醒一个人。这反映了Pulse
.
现在想象你经营一家商店。当你关门时,顾客在店外等候。当您打开商店时,您不只是想叫醒一位顾客——他们现在都可以进来了。这反映了PulseAll
.
AMonitor
有两个队列:等待队列和就绪队列。在没有Wait
and的情况下Pulse
,所有试图获取锁的线程都进入就绪队列。当锁可用时,就绪队列中的一个线程将获取它。
当一个线程获得锁然后执行 aWait
时,该线程进入等待队列。它正在等待 a Pulse
or PulseAll
,并且将一直留在等待队列中,直到它收到 a Pulse
,即使就绪队列中的其他线程获取并释放锁也是如此。
Pulse
将一个线程从等待队列移动到就绪队列。 PulseAll
将所有线程从等待队列移动到就绪队列。
这里的关键是等待队列中的线程永远无法获得锁。它们正在等待一个脉冲将它们移回就绪队列,以便在可用时获取锁。
关于 Wait 和 Pulse 的讨论相当不错——至少有一点能让你开始——在这里。