释放对象上的锁并阻止当前线程,直到它重新获取该锁。
命名空间:System.Threading
程序集:mscorlib(在 mscorlib.dll 中)
要在其上等待的对象。
异常类型
条件
obj 参数为 空引用(在 Visual Basic 中为 Nothing)。
调用线程不拥有指定对象的锁。
调用 Wait 的线程稍后从等待状态中断。当另一个线程调用此线程的 Interrupt 方法时会发生这种情况。
当前拥有指定对象上的锁的线程调用此方法以释放该对象,以便其他线程可以访问它。调用方在等待重新获取锁期间被阻止。当调用方需要等待另一个线程操作导致的状态更改时,将调用此方法。
当线程调用 Wait 时,它释放对象的锁并进入对象的等待队列。对象的就绪队列中的下一个线程(如果有)获取锁并拥有对对象的独占使用。所有调用 Wait 的线程都将留在等待队列中,直到它们接收到由锁的所有者发送的 Pulse 或 PulseAll 的信号为止。如果发送了 Pulse,则只影响位于等待队列最前面的线程。如果发送了 PulseAll,则将影响正等待该对象的所有线程。接收到信号后,一个或多个线程将离开等待队列而进入就绪队列。就绪队列中的线程被允许重新获取锁。
当调用线程重新获取对象上的锁后,此方法将返回。请注意,如果锁的持有者不调用 Pulse 或 PulseAll,则此方法将无限期地阻止。
调用方执行一次 Wait,与已为指定对象调用 Enter 的次数无关。概念上,Wait 方法存储调用方对对象调用 Enter 的次数,并按完全释放锁定对象所需要的次数调用 Exit。然后调用方在等待重新获取对象期间被阻止。当调用方重新获取锁时,系统按还原调用方的已保存 Enter 计数所需要的次数调用 Enter。调用 Wait 仅释放指定对象的锁;如果调用方是其他对象的锁的所有者,则不释放这些锁。
请注意,同步的对象包含若干引用,其中包括对当前拥有锁的线程的引用、对就绪队列(包含准备获取锁的线程)的引用和对等待队列(包含等待对象状态更改通知的线程)的引用。
Pulse、 PulseAll 和 Wait 方法必须从同步的代码块内调用。
Pulse 方法的备注解释如果在没有任何线程在等待时调用 Pulse 会发生什么情况。
通知等待队列中的线程锁定对象状态的更改。
命名空间:System.Threading
程序集:mscorlib(在 mscorlib.dll 中)
线程正在等待的对象。
异常类型
条件
obj 参数为 空引用(在 Visual Basic 中为 Nothing)。
调用线程不拥有指定对象的锁。
只有锁的当前所有者可以使用 Pulse 向等待对象发出信号。
当前拥有指定对象上的锁的线程调用此方法以便向队列中的下一个线程发出锁的信号。接收到脉冲后,等待线程就被移动到就绪队列中。在调用 Pulse 的线程释放锁后,就绪队列中的下一个线程(不一定是接收到脉冲的线程)将获得该锁。
重要事项:
Monitor 类不对指示 Pulse 方法已被调用的状态进行维护。因此,如果您在没有等待线程时调用 Pulse,则下一个调用 Wait 的线程将阻止,似乎 Pulse 从未被调用过。如果两个线程正在使用 Pulse 和 Wait 交互,则可能导致死锁。将其与 AutoResetEvent 类的行为相比较:如果您通过调用 AutoResetEvent 的 Set 方法向其发送信号,在没有等待线程时,AutoResetEvent 将一直保持终止状态,直到线程调用 WaitOne、WaitAny 或 WaitAll。AutoResetEvent 释放该线程并返回到未终止状态。
请注意,同步的对象包含若干引用,其中包括对当前拥有锁的线程的引用、对就绪队列(包含准备获取锁的线程)的引用和对等待队列(包含等待对象状态更改通知的线程)的引用。
Pulse、 PulseAll 和 Wait 方法必须从同步的代码块内调用。
若要向多个线程发送信号,请使用 PulseAll 方法。
请参考下面的文章:
调用Pulse方法时,如果ready队列中没有处于WaitSleepJoin状态的线程,则即使以后有这样的线程出现了,即使之前Pulse过n次,也是没有作用滴(http://www.cnblogs.com/lovesanni/archive/2008/06/25/1229893.html)