Monitor.Pulse 方法

通知等待队列中的线程锁定对象状态的更改。

**命名空间:**System.Threading
**程序集:**mscorlib(在 mscorlib.dll 中)

语法

声明
Public Shared Sub Pulse ( _
    obj As Object _
)
用法
Dim obj As Object

Monitor.Pulse(obj)
public static void Pulse (
    Object obj
)
public:
static void Pulse (
    Object^ obj
)
public static void Pulse (
    Object obj
)
public static function Pulse (
    obj : Object
)

参数

  • obj
    线程正在等待的对象。

异常

异常类型 条件

ArgumentNullException

obj 参数为 空引用(在 Visual Basic 中为 Nothing)。

SynchronizationLockException

调用线程不拥有指定对象的锁。

备注

只有锁的当前所有者可以使用 Pulse 向等待对象发出信号。

当前拥有指定对象上的锁的线程调用此方法以便向队列中的下一个线程发出锁的信号。接收到脉冲后,等待线程就被移动到就绪队列中。在调用 Pulse 的线程释放锁后,就绪队列中的下一个线程(不一定是接收到脉冲的线程)将获得该锁。

Note重要事项:

Monitor 类不对指示 Pulse 方法已被调用的状态进行维护。因此,如果您在没有等待线程时调用 Pulse,则下一个调用 Wait 的线程将阻止,似乎 Pulse 从未被调用过。如果两个线程正在使用 PulseWait 交互,则可能导致死锁。将其与 AutoResetEvent 类的行为相比较:如果您通过调用 AutoResetEventSet 方法向其发送信号,在没有等待线程时,AutoResetEvent 将一直保持终止状态,直到线程调用 WaitOneWaitAnyWaitAllAutoResetEvent 释放该线程并返回到未终止状态。

请注意,同步的对象包含若干引用,其中包括对当前拥有锁的线程的引用、对就绪队列(包含准备获取锁的线程)的引用和对等待队列(包含等待对象状态更改通知的线程)的引用。

PulsePulseAllWait 方法必须从同步的代码块内调用。

若要向多个线程发送信号,请使用 PulseAll 方法。

示例

下面的代码示例说明如何使用 Pulse 方法。

Imports System
Imports System.Threading
Imports System.Collections


Namespace MonitorCS1
   Class MonitorSample
      Private MAX_LOOP_TIME As Integer = 1000
      Private m_smplQueue As Queue
      
      
      Public Sub New()
         m_smplQueue = New Queue()
      End Sub 'New
      
      Public Sub FirstThread()
         Dim counter As Integer = 0
         SyncLock m_smplQueue
            While counter < MAX_LOOP_TIME
               'Wait, if the queue is busy.
               Monitor.Wait(m_smplQueue)
               'Push one element.
               m_smplQueue.Enqueue(counter)
               'Release the waiting thread.
               Monitor.Pulse(m_smplQueue)
               
               counter += 1
            End While
         End SyncLock
      End Sub 'FirstThread
      
      Public Sub SecondThread()
         SyncLock m_smplQueue
            'Release the waiting thread.
            Monitor.Pulse(m_smplQueue)
            'Wait in the loop while the queue is busy.
            'Exit on the time-out when the first thread stops. 
            While Monitor.Wait(m_smplQueue, 1000)
               'Pop the first element.
               Dim counter As Integer = CInt(m_smplQueue.Dequeue())
               'Print the first element.
               Console.WriteLine(counter.ToString())
               'Release the waiting thread.
               Monitor.Pulse(m_smplQueue)
            End While
         End SyncLock
      End Sub 'SecondThread
      
      'Return the number of queue elements.
      Public Function GetQueueCount() As Integer
         Return m_smplQueue.Count
      End Function 'GetQueueCount
      
      Public Shared Sub Main(args() As String)
         'Create the MonitorSample object.
         Dim test As New MonitorSample()
         'Create the first thread.
         Dim tFirst As New Thread(AddressOf test.FirstThread)
         'Create the second thread.
         Dim tSecond As New Thread(AddressOf test.SecondThread)
         'Start threads.
         tFirst.Start()
         tSecond.Start()
         'wait to the end of the two threads
         tFirst.Join()
         tSecond.Join()
         'Print the number of queue elements.
         Console.WriteLine(("Queue Count = " + test.GetQueueCount().ToString()))
      End Sub 'Main
   End Class 'MonitorSample
End Namespace 'MonitorCS1 
using System;
using System.Threading;
using System.Collections;

namespace MonitorCS1
{
    class MonitorSample
    {
        const int MAX_LOOP_TIME = 1000;
        Queue   m_smplQueue;

        public MonitorSample()
        {
            m_smplQueue = new Queue(); 
        }
        public void FirstThread()
        {
            int counter = 0;
            lock(m_smplQueue)
            {
                while(counter < MAX_LOOP_TIME)
                {
                    //Wait, if the queue is busy.
                    Monitor.Wait(m_smplQueue);
                    //Push one element.
                    m_smplQueue.Enqueue(counter);
                    //Release the waiting thread.
                    Monitor.Pulse(m_smplQueue); 

                    counter++;
                }
            }
        }
        public void SecondThread()
        {
            lock(m_smplQueue)
            {
                //Release the waiting thread.
                Monitor.Pulse(m_smplQueue);
                //Wait in the loop, while the queue is busy.
                //Exit on the time-out when the first thread stops. 
                while(Monitor.Wait(m_smplQueue,1000))
                {
                    //Pop the first element.
                    int counter = (int)m_smplQueue.Dequeue();
                    //Print the first element.
                    Console.WriteLine(counter.ToString());
                    //Release the waiting thread.
                    Monitor.Pulse(m_smplQueue);
                }
            }
        }
        //Return the number of queue elements.
        public int GetQueueCount()
        {
            return m_smplQueue.Count;
        }

        static void Main(string[] args)
        {
            //Create the MonitorSample object.
            MonitorSample test = new MonitorSample();           
            //Create the first thread.
            Thread tFirst = new Thread(new ThreadStart(test.FirstThread));
            //Create the second thread.
            Thread tSecond = new Thread(new ThreadStart(test.SecondThread));
            //Start threads.
            tFirst.Start();
            tSecond.Start();
            //wait to the end of the two threads
            tFirst.Join();
            tSecond.Join();         
            //Print the number of queue elements.
            Console.WriteLine("Queue Count = " + test.GetQueueCount().ToString());
        }
    }
}
using namespace System;
using namespace System::Threading;
using namespace System::Collections;
ref class MonitorSample
{
public:
   MonitorSample();
   void FirstThread();
   void SecondThread();
   int GetQueueCount();

private:
   literal int MAX_LOOP_TIME = 1000;
   Queue^ m_smplQueue;
};

MonitorSample::MonitorSample()
{
   m_smplQueue = gcnew Queue;
}

void MonitorSample::FirstThread()
{
   int counter = 0;
   Monitor::Enter( m_smplQueue );
   while ( counter < MAX_LOOP_TIME )
   {
      
      //Wait, if the queue is busy.
      Monitor::Wait( m_smplQueue );
      
      //Push one element.
      m_smplQueue->Enqueue( counter );
      
      //Release the waiting thread.
      Monitor::Pulse( m_smplQueue );
      counter++;
   }

   Monitor::Exit( m_smplQueue );
}

void MonitorSample::SecondThread()
{
   Monitor::Enter( m_smplQueue );
   
   //Release the waiting thread.
   Monitor::Pulse( m_smplQueue );
   
   //Wait in the loop, while the queue is busy.
   //Exit on the time-out when the first thread stopped. 
   while ( Monitor::Wait( m_smplQueue, 1000 ) )
   {
      
      //Pop the first element.
      int counter =  *dynamic_cast<int^>(m_smplQueue->Dequeue());
      
      //Print the first element.
      Console::WriteLine( counter.ToString() );
      
      //Release the waiting thread.
      Monitor::Pulse( m_smplQueue );
   }

   Monitor::Exit( m_smplQueue );
}


//Return the number of queue elements.
int MonitorSample::GetQueueCount()
{
   return m_smplQueue->Count;
}

int main()
{
   
   //Create the MonitorSample object.
   MonitorSample^ test = gcnew MonitorSample;
   
   //Create the first thread.
   Thread^ tFirst = gcnew Thread( gcnew ThreadStart( test, &MonitorSample::FirstThread ) );
   
   //Create the second thread.
   Thread^ tSecond = gcnew Thread( gcnew ThreadStart( test, &MonitorSample::SecondThread ) );
   
   //Start threads.
   tFirst->Start();
   tSecond->Start();
   
   //wait to the end of the two threads
   tFirst->Join();
   tSecond->Join();
   
   //Print the number of queue elements.
   Console::WriteLine( String::Concat( "Queue Count = ", test->GetQueueCount().ToString() ) );
}
package MonitorJSL1;

import System.*;
import System.Threading.*;
import System.Collections.*;

class MonitorSample
{
    private int MAX_LOOP_TIME = 1000;
    private Queue mSmplQueue;

    public MonitorSample()
    {
        mSmplQueue = new Queue();
    } //MonitorSample

    public void FirstThread()
    {
        int counter = 0;
        synchronized (mSmplQueue) {
            while (counter < MAX_LOOP_TIME) {
                //Wait, if the queue is busy.
                Monitor.Wait(mSmplQueue);

                //Push one element.
                mSmplQueue.Enqueue((Int32)counter);

                //Release the waiting thread.
                Monitor.Pulse(mSmplQueue);
                counter++;
            }
        }
    } //FirstThread

    public void SecondThread()
    {
        synchronized (mSmplQueue) {
            //Release the waiting thread.
            Monitor.Pulse(mSmplQueue);

            //Wait in the loop, while the queue is busy.
            //Exit on the time-out when the first thread stops. 
            while (Monitor.Wait(mSmplQueue, 1000)) {
                //Pop the first element.
                int counter = Convert.ToInt32(mSmplQueue.Dequeue());

                //Print the first element.
                Console.WriteLine(Convert.ToString(counter));

                //Release the waiting thread.
                Monitor.Pulse(mSmplQueue);
            }
        }
    } //SecondThread

    //Return the number of queue elements.
    public int GetQueueCount()
    {
        return mSmplQueue.get_Count();
    } //GetQueueCount

    public static void main(String[] args)
    {
        //Create the MonitorSample object.
        MonitorSample test = new MonitorSample();

        //Create the first thread.
        System.Threading.Thread tFirst = 
            new System.Threading.Thread(new ThreadStart(test.FirstThread));

        //Create the second thread.
        System.Threading.Thread tSecond = 
            new System.Threading.Thread(new ThreadStart(test.SecondThread));

        //Start threads.
        tFirst.Start();
        tSecond.Start();

        //wait to the end of the two threads
        tFirst.Join();
        tSecond.Join();

        //Print the number of queue elements.
        Console.WriteLine("Queue Count = "
            + Convert.ToString(test.GetQueueCount()));
    } //main
} //MonitorSample

平台

Windows 98、Windows 2000 SP4、Windows Millennium Edition、Windows Server 2003、Windows XP Media Center Edition、Windows XP Professional x64 Edition、Windows XP SP2、Windows XP Starter Edition

.NET Framework 并不是对每个平台的所有版本都提供支持。有关受支持版本的列表,请参见系统要求

版本信息

.NET Framework

受以下版本支持:2.0、1.1、1.0

请参见

参考

Monitor 类
Monitor 成员
System.Threading 命名空间
Thread

其他资源

托管线程处理
监视器