次の方法で共有


Monitor.Pulse メソッド

ロックされたオブジェクトの状態が変更されたことを、待機キュー内のスレッドに通知します。

Public Shared Sub Pulse( _
   ByVal obj As Object _)
[C#]
public static void Pulse(objectobj);
[C++]
public: static void Pulse(Object* obj);
[JScript]
public static function Pulse(
   obj : Object);

パラメータ

  • obj
    スレッドが待機するオブジェクト。

例外

例外の種類 条件
ArgumentNullException obj パラメータが null 参照 (Visual Basic では Nothing) です。
SynchronizationLockException 呼び出し元のスレッドは、指定したオブジェクトのロックを所有していません。

解説

Pulse を使用して待機中のオブジェクトに通知できるのは、ロックの現在の所有者だけです。

指定したオブジェクトのロックを現在所有しているスレッドは、このメソッドを呼び出して、ロックの取得を待機している次のスレッドに通知します。待機中のスレッドは、パルスを受信すると実行待ちキューへ移動します。 Pulse を呼び出したスレッドがロックを解放すると、実行待ちキュー内の次のスレッドがロックを取得します。このスレッドは、必ずしもパルスを受け取ったスレッドになるとは限りません。

同期されたオブジェクトは、現在ロックを保持しているスレッドへの参照、ロックを取得する準備ができているスレッドを格納している実行待ちキューへの参照、オブジェクトの状態の変更通知を待機しているスレッドを格納している待機キューへの参照など、複数の参照を保持しています。 PulsePulseAllWait の各メソッドは、同期されたコードのブロック内から呼び出される必要があります。 Wait(Object, Int32) の解説では、 PulseWait の前に呼び出されると発生する問題について説明しています。

複数のスレッドに通知するには、 PulseAll メソッドを使用します。

使用例

[Visual Basic, C#, C++] 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 

[C#] 
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());
        }
    }
}

[C++] 
#using <mscorlib.dll>

using namespace System;
using namespace System::Threading;
using namespace System::Collections;

__gc class MonitorSample
{
public:
    MonitorSample();
    void FirstThread();
    void SecondThread();
    int GetQueueCount();

private:
    static const int MAX_LOOP_TIME = 1000;
    Queue*    m_smplQueue;
};

MonitorSample::MonitorSample()
{
    m_smplQueue = new 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(__box(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<__box 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 = new MonitorSample();         
    //Create the first thread.
    Thread* tFirst = new Thread(new ThreadStart(test, &MonitorSample::FirstThread));
    //Create the second thread.
    Thread* tSecond = new Thread(new 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(S"Queue Count = ", test->GetQueueCount().ToString()));
}

[JScript] JScript のサンプルはありません。Visual Basic、C#、および C++ のサンプルを表示するには、このページの左上隅にある言語のフィルタ ボタン 言語のフィルタ をクリックします。

必要条件

プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ, Common Language Infrastructure (CLI) Standard

参照

Monitor クラス | Monitor メンバ | System.Threading 名前空間 | Thread | スレッド処理 | Monitor