Delphi Docwiki 解释说,只要调用线程释放对象, Pulse就会通知等待队列中的下一个线程,它将能够锁定指定的对象。PulseAll向等待队列中的所有线程发出信号。
我发现这段代码在线程队列实现中使用了 Pulse,并给出了上面的定义,认为应该使用 PulseAll - 或者以不同的方式询问:什么时候使用 Pulse 而不是 PulseAll 是正确的?(基本问题是:我如何确定“队列中的下一个线程”始终是需要通知的线程,除非在总共只有两个线程的琐碎情况下,或者代码可以安全假设唯一等待的线程是需要通知/“脉冲”的线程)?
function TSimpleThreadedQueue.Enqueue(const Item: T; Timeout: LongWord): TWaitResult;
begin
if Closed then Exit(wrAbandoned);
if not TMonitor.Enter(FQueue, Timeout) then Exit(wrTimeout);
try
if Closed then Exit(wrAbandoned);
FQueue.Enqueue(Item);
TMonitor.Pulse(FQueue);
Result := wrSignaled;
finally
TMonitor.Exit(FQueue);
end;
end;
对于Java语言中相应的同步方法,我发现了这个问题:Java: notify() vs. notifyAll() all over again
更新:上面链接的 Java 问题有一个有趣的答案,它显示了即使在只有两个方法 put 和 get 并且使用 notify()(Pulse() 的 Java 对应物)的生产者/消费者应用程序中也会发生死锁: Java: notify() vs. notifyAll() 再一次
答案包含建议
如果您不确定要使用哪个,请使用
notifyAll
.