Monitor.Exit メソッド
指定したオブジェクトの排他ロックを解放します。
Public Shared Sub Exit( _
ByVal obj As Object _)
[C#]
public static void Exit(objectobj);
[C++]
public: static void Exit(Object* obj);
[JScript]
public static function Exit(
obj : Object);
パラメータ
- obj
ロックを解放する対象となるオブジェクト。
例外
例外の種類 | 条件 |
---|---|
ArgumentNullException | obj パラメータが null 参照 (Visual Basic では Nothing) です。 |
SynchronizationLockException | 現在のスレッドが、指定したオブジェクトのロックを所有していません。 |
解説
呼び出し元は、 obj パラメータのロックを所有する必要があります。呼び出し元が指定したオブジェクトのロックを所有している場合は、そのオブジェクトの Exit と Enter を同じ回数呼び出すと、ロックが解放されます。呼び出し元が Enter と Exit を同じ回数呼び出さないと、ロックは解放されません。
ロックが解放されて、他のスレッドがオブジェクトの実行待ちキューに入ると、それらのスレッドの 1 つがロックを取得します。ロックを取得するために待機キュー内で待機している他のスレッドは、ロックの所有者が Exit を呼び出しても、実行待ちキューに自動で移動しません。1 つ以上の待機中のスレッドを実行待ちキューに移動するには、 Exit を呼び出す前に、 Pulse または PulseAll を呼び出します。
使用例
[Visual Basic, C#, C++] Exit メソッドを使用する方法の例を次に示します。
Imports System
Imports System.Threading
Imports System.Collections
Class MonitorSample
'Define the queue to safe thread access.
Private m_inputQueue As Queue
Public Sub New()
m_inputQueue = New Queue()
End Sub
'Add an element to the queue and obtain the monitor lock for the queue object.
Public Sub AddElement(ByVal qValue As Object)
'Lock the queue.
Monitor.Enter(m_inputQueue)
'Add an element.
m_inputQueue.Enqueue(qValue)
'Unlock the queue.
Monitor.Exit(m_inputQueue)
End Sub
'Try to add an element to the queue.
'Add the element to the queue only if the queue object is unlocked.
Public Function AddElementWithoutWait(ByVal qValue As Object) As Boolean
'Determine whether the queue is locked.
If Not Monitor.TryEnter(m_inputQueue) Then
Return False
Else
m_inputQueue.Enqueue(qValue)
Monitor.Exit(m_inputQueue)
Return True
End If
End Function
'Try to add an element to the queue.
'Add the element to the queue only if during the specified time the queue object will be unlocked.
Public Function WaitToAddElement(ByVal qValue As Object, ByVal waitTime As Integer) As Boolean
'Wait while the queue is locked.
If Not Monitor.TryEnter(m_inputQueue, waitTime) Then
Return False
Else
m_inputQueue.Enqueue(qValue)
Monitor.Exit(m_inputQueue)
Return True
End If
End Function
'Delete all elements that equal the given object and obtain the monitor lock for the queue object.
Public Sub DeleteElement(ByVal qValue As Object)
'Lock the queue.
Monitor.Enter(m_inputQueue)
Dim counter As Integer = m_inputQueue.Count
While (counter > 0)
'Check each element.
Dim elm As Object = m_inputQueue.Dequeue()
If Not elm.Equals(qValue) Then
m_inputQueue.Enqueue(elm)
End If
counter = counter - 1
End While
'Unlock the queue.
Monitor.Exit(m_inputQueue)
End Sub
'Print all queue elements.
Public Sub PrintAllElements()
'Lock the queue.
Monitor.Enter(m_inputQueue)
Dim elmEnum As IEnumerator = m_inputQueue.GetEnumerator()
While elmEnum.MoveNext()
'Print the next element.
Console.WriteLine(elmEnum.Current.ToString())
End While
'Unlock the queue.
Monitor.Exit(m_inputQueue)
End Sub
Public Shared Sub Main()
Dim sample As MonitorSample = New MonitorSample()
Dim i As Integer
For i = 0 To 29
sample.AddElement(i)
Next i
sample.PrintAllElements()
sample.DeleteElement(0)
sample.DeleteElement(10)
sample.DeleteElement(20)
sample.PrintAllElements()
End Sub
End Class
[C#]
using System;
using System.Collections;
using System.Threading;
namespace MonitorCS2
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class MonitorSample
{
//Define the queue to safe thread access.
private Queue m_inputQueue;
public MonitorSample()
{
m_inputQueue = new Queue();
}
//Add an element to the queue and obtain the monitor lock for the queue object.
public void AddElement(object qValue)
{
//Lock the queue.
Monitor.Enter(m_inputQueue);
//Add element
m_inputQueue.Enqueue(qValue);
//Unlock the queue.
Monitor.Exit(m_inputQueue);
}
//Try to add an element to the queue.
//Add the element to the queue only if the queue object is unlocked.
public bool AddElementWithoutWait(object qValue)
{
//Determine whether the queue is locked
if(!Monitor.TryEnter(m_inputQueue))
return false;
m_inputQueue.Enqueue(qValue);
Monitor.Exit(m_inputQueue);
return true;
}
//Try to add an element to the queue.
//Add the element to the queue only if during the specified time the queue object will be unlocked.
public bool WaitToAddElement(object qValue, int waitTime)
{
//Wait while the queue is locked.
if(!Monitor.TryEnter(m_inputQueue,waitTime))
return false;
m_inputQueue.Enqueue(qValue);
Monitor.Exit(m_inputQueue);
return true;
}
//Delete all elements that equal the given object and obtain the monitor lock for the queue object.
public void DeleteElement(object qValue)
{
//Lock the queue.
Monitor.Enter(m_inputQueue);
int counter = m_inputQueue.Count;
while(counter > 0)
{
//Check each element.
object elm = m_inputQueue.Dequeue();
if(!elm.Equals(qValue))
{
m_inputQueue.Enqueue(elm);
}
--counter;
}
//Unlock the queue.
Monitor.Exit(m_inputQueue);
}
//Print all queue elements.
public void PrintAllElements()
{
//Lock the queue.
Monitor.Enter(m_inputQueue);
IEnumerator elmEnum = m_inputQueue.GetEnumerator();
while(elmEnum.MoveNext())
{
//Print the next element.
Console.WriteLine(elmEnum.Current.ToString());
}
//Unlock the queue.
Monitor.Exit(m_inputQueue);
}
static void Main(string[] args)
{
MonitorSample sample = new MonitorSample();
for(int i = 0; i < 30; i++)
sample.AddElement(i);
sample.PrintAllElements();
sample.DeleteElement(0);
sample.DeleteElement(10);
sample.DeleteElement(20);
sample.PrintAllElements();
}
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
using namespace System::Collections;
using namespace System::Threading;
// Class definition
public __gc class MonitorSample {
public:
MonitorSample();
void AddElement(Object* qValue);
bool AddElementWithoutWait(Object* qValue);
bool WaitToAddElement(Object* qValue, int waitTime);
void DeleteElement(Object* qValue);
void PrintAllElements();
private:
Queue* m_inputQueue;
};
//Define the queue to safe thread access.
MonitorSample::MonitorSample()
{
m_inputQueue = new Queue();
}
//Add an element to the queue and obtain the monitor lock for the queue object.
void MonitorSample::AddElement(Object* qValue)
{
//Lock the queue.
Monitor::Enter(m_inputQueue);
//Add element
m_inputQueue->Enqueue(qValue);
//Unlock the queue.
Monitor::Exit(m_inputQueue);
}
//Try to add an element to the queue.
//Add the element to the queue only if the queue object is unlocked.
bool MonitorSample::AddElementWithoutWait(Object* qValue)
{
//Determine whether the queue is locked
if(!Monitor::TryEnter(m_inputQueue))
return false;
m_inputQueue->Enqueue(qValue);
Monitor::Exit(m_inputQueue);
return true;
}
//Try to add an element to the queue.
//Add the element to the queue only if during the specified time the queue object will be unlocked.
bool MonitorSample::WaitToAddElement(Object* qValue, int waitTime)
{
//Wait while the queue is locked.
if(!Monitor::TryEnter(m_inputQueue,waitTime))
return false;
m_inputQueue->Enqueue(qValue);
Monitor::Exit(m_inputQueue);
return true;
}
//Delete all elements that equal the given object and obtain the monitor lock for the queue object.
void MonitorSample::DeleteElement(Object* qValue)
{
//Lock the queue.
Monitor::Enter(m_inputQueue);
int counter = m_inputQueue->Count;
while(counter > 0)
{
//Check each element.
Object* elm = m_inputQueue->Dequeue();
if(!elm->Equals(qValue))
{
m_inputQueue->Enqueue(elm);
}
--counter;
}
//Unlock the queue.
Monitor::Exit(m_inputQueue);
}
//Print all queue elements.
void MonitorSample::PrintAllElements()
{
//Lock the queue.
Monitor::Enter(m_inputQueue);
IEnumerator* elmEnum = m_inputQueue->GetEnumerator();
while(elmEnum->MoveNext())
{
//Print the next element.
Console::WriteLine(elmEnum->Current->ToString());
}
//Unlock the queue.
Monitor::Exit(m_inputQueue);
}
int main() {
MonitorSample* sample = new MonitorSample();
for(int i = 0; i < 30; i++)
sample->AddElement(__box(i));
sample->PrintAllElements();
sample->DeleteElement(__box(0));
sample->DeleteElement(__box(10));
sample->DeleteElement(__box(20));
sample->PrintAllElements();
}
[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 ファミリ, .NET Compact Framework - Windows CE .NET, Common Language Infrastructure (CLI) Standard
参照
Monitor クラス | Monitor メンバ | System.Threading 名前空間 | Thread | スレッド処理 | Monitor