ReaderWriterLock クラス
アセンブリ: mscorlib (mscorlib.dll 内)

<ComVisibleAttribute(True)> _ Public NotInheritable Class ReaderWriterLock Inherits CriticalFinalizerObject
[ComVisibleAttribute(true)] public ref class ReaderWriterLock sealed : public CriticalFinalizerObject

![]() |
---|
このクラスに適用される HostProtectionAttribute 属性の Resources プロパティの値は、Synchronization または ExternalThreading です。HostProtectionAttribute は、デスクトップ アプリケーション (一般的には、アイコンをダブルクリック、コマンドを入力、またはブラウザに URL を入力して起動するアプリケーション) には影響しません。詳細については、HostProtectionAttribute クラスのトピックまたは「SQL Server プログラミングとホスト保護属性」を参照してください。 |
ReaderWriterLock は、リソースへのアクセスを同期するときに使用します。このクラスでは、複数のスレッドによる同時読み取りアクセスまたは 1 つのスレッドによる書き込みアクセスのいずれかが常に許可されます。リソースの変更が頻繁に発生しない場合は、ReaderWriterLock のような "一度に 1 つ" 方式の単純なロックより、Monitor の方が優れたスループットを得ることができます。
ReaderWriterLock は、ほとんどのアクセスが読み取りアクセスで、書き込みアクセスはほとんど発生せず、短時間で終了するような場合に適しています。複数リーダーと単一ライタは交互に処理されるため、リーダーとライタの両方が長時間にわたってブロックされることはありません。
![]() |
---|
リーダー ロックまたはライタ ロックを長時間にわたって保持すると、他のスレッドが処理を続行できなくなります。最適なパフォーマンスを得るためには、書き込みの時間が短くなるようにアプリケーションを設計してください。 |
1 つのスレッドはリーダー ロックまたはライタ ロックを保持できますが、一度に両方を取得することはできません。ライタ ロックを取得するためにリーダー ロックを解放する必要がある場合は、代わりに UpgradeToWriterLock と DowngradeFromWriterLock を使用することもできます。
再帰的にロックを要求すると、ロックのロック カウントがインクリメントされます。
リーダーとライタのキューは別々に存在します。ライタ ロックを保持していたスレッドがロックを解放すると、そのときリーダー キューで待機していたすべてのスレッドに対してリーダー ロックが与えられます。これによりリーダー ロックを保持していたすべてのスレッドがロックを解放すると、今度はライタ キューで待機していた次のスレッドにライタ ロックが与えられます。これが繰り返されます。つまり、ReaderWriterLock は、複数のリーダーと 1 つのライタを交互に処理します。
現在のリーダー ロックの解放を待機しているスレッドがライタ キューにある場合、新しくリーダー ロックを要求するスレッドはリーダー キューに格納されます。この場合、既にリーダー ロックを保持しているスレッドと同時アクセスを共有できたとしても、この新しいリーダー ロックの要求はすぐには処理されません。これは、リーダーによる無制限のブロックからライタを保護するためのしくみです。
ReaderWriterLock のロック取得に関するメソッドのほとんどは、タイムアウト値を受け取ることができます。タイムアウト値を使用すると、アプリケーションでデッドロックが発生することを防ぐことができます。たとえば、あるスレッドがあるリソースに対してライタ ロックを取得し、次に 2 番目のリソースに対してリーダー ロックを要求、同時に別のスレッドがこの 2 番目のリソースに対してライタ ロックを取得して、1 番目のリソースに対してリーダー ロックを要求したとします。このような場合は、タイムアウト値を使用しないと、2 つのスレッドでデッドロックが発生します。
タイムアウト時間が経過して、ロック要求が許可されなかった場合、メソッドは ApplicationException をスローして制御を呼び出し元のスレッドに戻します。スレッドはこの例外をキャッチして、次に実行するアクションを指定できます。
タイムアウト値はミリ秒単位で表されます。System.TimeSpan を使用してタイムアウト値を指定する場合、使用される値は、TimeSpan が表すミリ秒数の合計値となります。有効なタイムアウト値 (ミリ秒) を次の表示に示します。
-1 を例外として、タイムアウト値には負の値を指定できません。-1 以外の負の整数値を指定した場合、タイムアウト値には 0 (タイムアウトなし) が適用されます。-1 以外の負のミリ秒値を表す TimeSpan を指定した場合は、ArgumentOutOfRangeException がスローされます。

' This example shows a ReaderWriterLock protecting a shared ' resource that is read concurrently and written exclusively ' by multiple threads. ' The complete code is located in the ReaderWriterLock ' class topic. Imports System Imports System.Threading Imports Microsoft.VisualBasic Public Class Test ' Declaring the ReaderWriterLock at the class level ' makes it visible to all threads. Private Shared rwl As New ReaderWriterLock() ' For this example, the shared resource protected by the ' ReaderWriterLock is just an integer. Private Shared resource As Integer = 0 Const numThreads As Integer = 26 Private Shared running As Boolean = True Private Shared rnd As New Random() ' Statistics. Private Shared readerTimeouts As Integer = 0 Private Shared writerTimeouts As Integer = 0 Private Shared reads As Integer = 0 Private Shared writes As Integer = 0 <MTAThread> _ Public Shared Sub Main(args() As String) ' Start a series of threads. Each thread randomly ' performs reads and writes on the shared resource. Dim t(numThreads) As Thread Dim i As Integer For i = 0 To numThreads - 1 t(i) = New Thread(New ThreadStart(AddressOf ThreadProc)) t(i).Name = Chr(i + 65) t(i).Start() If i > 10 Then Thread.Sleep(300) End If Next i ' Tell the threads to shut down, then wait until they all ' finish. running = False For i = 0 To numThreads - 1 t(i).Join() Next i ' Display statistics. Console.WriteLine(vbCrLf & "{0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.", reads, writes, readerTimeouts, writerTimeouts) Console.WriteLine("Press ENTER to exit.") Console.ReadLine() End Sub 'Main Shared Sub ThreadProc() ' As long as a thread runs, it randomly selects ' various ways to read and write from the shared ' resource. Each of the methods demonstrates one ' or more features of ReaderWriterLock. While running Dim action As Double = rnd.NextDouble() If action < 0.8 Then ReadFromResource(10) ElseIf action < 0.81 Then ReleaseRestore(50) ElseIf action < 0.9 Then UpgradeDowngrade(100) Else WriteToResource(100) End If End While End Sub 'ThreadProc ' Shows how to request and release a reader lock, and ' how to handle time-outs. Shared Sub ReadFromResource(timeOut As Integer) Try rwl.AcquireReaderLock(timeOut) Try ' It is safe for this thread to read from ' the shared resource. Display("reads resource value " & resource) Interlocked.Increment(reads) Finally ' Ensure that the lock is released. rwl.ReleaseReaderLock() End Try Catch ex As ApplicationException ' The reader lock request timed out. Interlocked.Increment(readerTimeouts) End Try End Sub 'ReadFromResource ' Shows how to request and release the writer lock, and ' how to handle time-outs. Shared Sub WriteToResource(timeOut As Integer) Try rwl.AcquireWriterLock(timeOut) Try ' It is safe for this thread to read or write ' from the shared resource. resource = rnd.Next(500) Display("writes resource value " & resource) Interlocked.Increment(writes) Finally ' Ensure that the lock is released. rwl.ReleaseWriterLock() End Try Catch ex As ApplicationException ' The writer lock request timed out. Interlocked.Increment(writerTimeouts) End Try End Sub 'WriteToResource ' Shows how to request a reader lock, upgrade the ' reader lock to the writer lock, and downgrade to a ' reader lock again. Shared Sub UpgradeDowngrade(timeOut As Integer) Try rwl.AcquireReaderLock(timeOut) Try ' It is safe for this thread to read from ' the shared resource. Display("reads resource value " & resource) Interlocked.Increment(reads) ' If it is necessary to write to the resource, ' you must either release the reader lock and ' then request the writer lock, or upgrade the ' reader lock. Note that upgrading the reader lock ' puts the thread in the write queue, behind any ' other threads that might be waiting for the ' writer lock. Try Dim lc As LockCookie = rwl.UpgradeToWriterLock(timeOut) Try ' It is safe for this thread to read or write ' from the shared resource. resource = rnd.Next(500) Display("writes resource value " & resource) Interlocked.Increment(writes) Finally ' Ensure that the lock is released. rwl.DowngradeFromWriterLock(lc) End Try Catch ex As ApplicationException ' The upgrade request timed out. Interlocked.Increment(writerTimeouts) End Try ' When the lock has been downgraded, it is ' still safe to read from the resource. Display("reads resource value " & resource) Interlocked.Increment(reads) Finally ' Ensure that the lock is released. rwl.ReleaseReaderLock() End Try Catch ex As ApplicationException ' The reader lock request timed out. Interlocked.Increment(readerTimeouts) End Try End Sub 'UpgradeDowngrade ' Shows how to release all locks and later restore ' the lock state. Shows how to use sequence numbers ' to determine whether another thread has obtained ' a writer lock since this thread last accessed the ' resource. Shared Sub ReleaseRestore(timeOut As Integer) Dim lastWriter As Integer Try rwl.AcquireReaderLock(timeOut) Try ' It is safe for this thread to read from ' the shared resource. Cache the value. (You ' might do this if reading the resource is ' an expensive operation.) Dim resourceValue As Integer = resource Display("reads resource value " & resourceValue) Interlocked.Increment(reads) ' Save the current writer sequence number. lastWriter = rwl.WriterSeqNum ' Release the lock, and save a cookie so the ' lock can be restored later. Dim lc As LockCookie = rwl.ReleaseLock() ' Wait for a random interval (up to a ' quarter of a second), and then restore ' the previous state of the lock. Note that ' there is no time-out on the Restore method. Thread.Sleep(rnd.Next(250)) rwl.RestoreLock(lc) ' Check whether other threads obtained the ' writer lock in the interval. If not, then ' the cached value of the resource is still ' valid. If rwl.AnyWritersSince(lastWriter) Then resourceValue = resource Interlocked.Increment(reads) Display("resource has changed " & resourceValue) Else Display("resource has not changed " & resourceValue) End If Finally ' Ensure that the lock is released. rwl.ReleaseReaderLock() End Try Catch ex As ApplicationException ' The reader lock request timed out. Interlocked.Increment(readerTimeouts) End Try End Sub 'ReleaseRestore ' Helper method briefly displays the most recent ' thread action. Comment out calls to Display to ' get a better idea of throughput. Shared Sub Display(msg As String) Console.Write("Thread {0} {1}. " & vbCr, Thread.CurrentThread.Name, msg) End Sub 'Display End Class 'Test
// This example shows a ReaderWriterLock protecting a shared // resource that is read concurrently and written exclusively // by multiple threads. // The complete code is located in the ReaderWriterLock // class topic. using System; using System.Threading; public class Test { // Declaring the ReaderWriterLock at the class level // makes it visible to all threads. static ReaderWriterLock rwl = new ReaderWriterLock(); // For this example, the shared resource protected by the // ReaderWriterLock is just an integer. static int resource = 0; const int numThreads = 26; static bool running = true; static Random rnd = new Random(); // Statistics. static int readerTimeouts = 0; static int writerTimeouts = 0; static int reads = 0; static int writes = 0; public static void Main(string[] args) { // Start a series of threads. Each thread randomly // performs reads and writes on the shared resource. Thread[] t = new Thread[numThreads]; for (int i = 0; i < numThreads; i++) { t[i] = new Thread(new ThreadStart(ThreadProc)); t[i].Name = new String(Convert.ToChar(i + 65), 1); t[i].Start(); if (i > 10) Thread.Sleep(300); } // Tell the threads to shut down, then wait until they all // finish. running = false; for (int i = 0; i < numThreads; i++) { t[i].Join(); } // Display statistics. Console.WriteLine("\r\n{0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.", reads, writes, readerTimeouts, writerTimeouts); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); } static void ThreadProc() { // As long as a thread runs, it randomly selects // various ways to read and write from the shared // resource. Each of the methods demonstrates one // or more features of ReaderWriterLock. while (running) { double action = rnd.NextDouble(); if (action < .8) ReadFromResource(10); else if (action < .81) ReleaseRestore(50); else if (action < .90) UpgradeDowngrade(100); else WriteToResource(100); } } // Shows how to request and release a reader lock, and // how to handle time-outs. static void ReadFromResource(int timeOut) { try { rwl.AcquireReaderLock(timeOut); try { // It is safe for this thread to read from // the shared resource. Display("reads resource value " + resource); Interlocked.Increment(ref reads); } finally { // Ensure that the lock is released. rwl.ReleaseReaderLock(); } } catch (ApplicationException) { // The reader lock request timed out. Interlocked.Increment(ref readerTimeouts); } } // Shows how to request and release the writer lock, and // how to handle time-outs. static void WriteToResource(int timeOut) { try { rwl.AcquireWriterLock(timeOut); try { // It is safe for this thread to read or write // from the shared resource. resource = rnd.Next(500); Display("writes resource value " + resource); Interlocked.Increment(ref writes); } finally { // Ensure that the lock is released. rwl.ReleaseWriterLock(); } } catch (ApplicationException) { // The writer lock request timed out. Interlocked.Increment(ref writerTimeouts); } } // Shows how to request a reader lock, upgrade the // reader lock to the writer lock, and downgrade to a // reader lock again. static void UpgradeDowngrade(int timeOut) { try { rwl.AcquireReaderLock(timeOut); try { // It is safe for this thread to read from // the shared resource. Display("reads resource value " + resource); Interlocked.Increment(ref reads); // If it is necessary to write to the resource, // you must either release the reader lock and // then request the writer lock, or upgrade the // reader lock. Note that upgrading the reader lock // puts the thread in the write queue, behind any // other threads that might be waiting for the // writer lock. try { LockCookie lc = rwl.UpgradeToWriterLock(timeOut); try { // It is safe for this thread to read or write // from the shared resource. resource = rnd.Next(500); Display("writes resource value " + resource); Interlocked.Increment(ref writes); } finally { // Ensure that the lock is released. rwl.DowngradeFromWriterLock(ref lc); } } catch (ApplicationException) { // The upgrade request timed out. Interlocked.Increment(ref writerTimeouts); } // When the lock has been downgraded, it is // still safe to read from the resource. Display("reads resource value " + resource); Interlocked.Increment(ref reads); } finally { // Ensure that the lock is released. rwl.ReleaseReaderLock(); } } catch (ApplicationException) { // The reader lock request timed out. Interlocked.Increment(ref readerTimeouts); } } // Shows how to release all locks and later restore // the lock state. Shows how to use sequence numbers // to determine whether another thread has obtained // a writer lock since this thread last accessed the // resource. static void ReleaseRestore(int timeOut) { int lastWriter; try { rwl.AcquireReaderLock(timeOut); try { // It is safe for this thread to read from // the shared resource. Cache the value. (You // might do this if reading the resource is // an expensive operation.) int resourceValue = resource; Display("reads resource value " + resourceValue); Interlocked.Increment(ref reads); // Save the current writer sequence number. lastWriter = rwl.WriterSeqNum; // Release the lock, and save a cookie so the // lock can be restored later. LockCookie lc = rwl.ReleaseLock(); // Wait for a random interval (up to a // quarter of a second), and then restore // the previous state of the lock. Note that // there is no time-out on the Restore method. Thread.Sleep(rnd.Next(250)); rwl.RestoreLock(ref lc); // Check whether other threads obtained the // writer lock in the interval. If not, then // the cached value of the resource is still // valid. if (rwl.AnyWritersSince(lastWriter)) { resourceValue = resource; Interlocked.Increment(ref reads); Display("resource has changed " + resourceValue); } else { Display("resource has not changed " + resourceValue); } } finally { // Ensure that the lock is released. rwl.ReleaseReaderLock(); } } catch (ApplicationException) { // The reader lock request timed out. Interlocked.Increment(ref readerTimeouts); } } // Helper method briefly displays the most recent // thread action. Comment out calls to Display to // get a better idea of throughput. static void Display(string msg) { Console.Write("Thread {0} {1}. \r", Thread.CurrentThread.Name, msg); } }
// This example shows a ReaderWriterLock protecting a shared // resource that is read concurrently and written exclusively // by multiple threads. // The complete code is located in the ReaderWriterLock // class topic. using namespace System; using namespace System::Threading; public ref class Test { public: // Declaring the ReaderWriterLock at the class level // makes it visible to all threads. static ReaderWriterLock^ rwl = gcnew ReaderWriterLock; // For this example, the shared resource protected by the // ReaderWriterLock is just an integer. static int resource = 0; literal int numThreads = 26; static bool running = true; static Random^ rnd = gcnew Random; // Statistics. static int readerTimeouts = 0; static int writerTimeouts = 0; static int reads = 0; static int writes = 0; static void ThreadProc() { // As long as a thread runs, it randomly selects // various ways to read and write from the shared // resource. Each of the methods demonstrates one // or more features of ReaderWriterLock. while ( running ) { double action = rnd->NextDouble(); if ( action < .8 ) ReadFromResource( 10 ); else if ( action < .81 ) ReleaseRestore( 50 ); else if ( action < .90 ) UpgradeDowngrade( 100 ); else WriteToResource( 100 ); } } // Shows how to request and release a reader lock, and // how to handle time-outs. static void ReadFromResource( int timeOut ) { try { rwl->AcquireReaderLock( timeOut ); try { // It is safe for this thread to read from // the shared resource. Display( String::Format( "reads resource value {0}", resource ) ); Interlocked::Increment( reads ); } finally { // Ensure that the lock is released. rwl->ReleaseReaderLock(); } } catch ( ApplicationException^ ) { // The reader lock request timed out. Interlocked::Increment( readerTimeouts ); } } // Shows how to request and release the writer lock, and // how to handle time-outs. static void WriteToResource( int timeOut ) { try { rwl->AcquireWriterLock( timeOut ); try { // It is safe for this thread to read or write // from the shared resource. resource = rnd->Next( 500 ); Display( String::Format( "writes resource value {0}", resource ) ); Interlocked::Increment( writes ); } finally { // Ensure that the lock is released. rwl->ReleaseWriterLock(); } } catch ( ApplicationException^ ) { // The writer lock request timed out. Interlocked::Increment( writerTimeouts ); } } // Shows how to request a reader lock, upgrade the // reader lock to the writer lock, and downgrade to a // reader lock again. static void UpgradeDowngrade( int timeOut ) { try { rwl->AcquireReaderLock( timeOut ); try { // It is safe for this thread to read from // the shared resource. Display( String::Format( "reads resource value {0}", resource ) ); Interlocked::Increment( reads ); // If it is necessary to write to the resource, // you must either release the reader lock and // then request the writer lock, or upgrade the // reader lock. Note that upgrading the reader lock // puts the thread in the write queue, behind any // other threads that might be waiting for the // writer lock. try { LockCookie lc = rwl->UpgradeToWriterLock( timeOut ); try { // It is safe for this thread to read or write // from the shared resource. resource = rnd->Next( 500 ); Display( String::Format( "writes resource value {0}", resource ) ); Interlocked::Increment( writes ); } finally { // Ensure that the lock is released. rwl->DowngradeFromWriterLock( lc ); } } catch ( ApplicationException^ ) { // The upgrade request timed out. Interlocked::Increment( writerTimeouts ); } // When the lock has been downgraded, it is // still safe to read from the resource. Display( String::Format( "reads resource value {0}", resource ) ); Interlocked::Increment( reads ); } finally { // Ensure that the lock is released. rwl->ReleaseReaderLock(); } } catch ( ApplicationException^ ) { // The reader lock request timed out. Interlocked::Increment( readerTimeouts ); } } // Shows how to release all locks and later restore // the lock state. Shows how to use sequence numbers // to determine whether another thread has obtained // a writer lock since this thread last accessed the // resource. static void ReleaseRestore( int timeOut ) { int lastWriter; try { rwl->AcquireReaderLock( timeOut ); try { // It is safe for this thread to read from // the shared resource. Cache the value. (You // might do this if reading the resource is // an expensive operation.) int resourceValue = resource; Display( String::Format( "reads resource value {0}", resourceValue ) ); Interlocked::Increment( reads ); // Save the current writer sequence number. lastWriter = rwl->WriterSeqNum; // Release the lock, and save a cookie so the // lock can be restored later. LockCookie lc = rwl->ReleaseLock(); // Wait for a random interval (up to a // quarter of a second), and then restore // the previous state of the lock. Note that // there is no timeout on the Restore method. Thread::Sleep( rnd->Next( 250 ) ); rwl->RestoreLock( lc ); // Check whether other threads obtained the // writer lock in the interval. If not, then // the cached value of the resource is still // valid. if ( rwl->AnyWritersSince( lastWriter ) ) { resourceValue = resource; Interlocked::Increment( reads ); Display( String::Format( "resource has changed {0}", resourceValue ) ); } else { Display( String::Format( "resource has not changed {0}", resourceValue ) ); } } finally { // Ensure that the lock is released. rwl->ReleaseReaderLock(); } } catch ( ApplicationException^ ) { // The reader lock request timed out. Interlocked::Increment( readerTimeouts ); } } // Helper method briefly displays the most recent // thread action. Comment out calls to Display to // get a better idea of throughput. static void Display( String^ msg ) { Console::Write( "Thread {0} {1}. \r", Thread::CurrentThread->Name, msg ); } }; int main() { array<String^>^args = Environment::GetCommandLineArgs(); // Start a series of threads. Each thread randomly // performs reads and writes on the shared resource. array<Thread^>^t = gcnew array<Thread^>(Test::numThreads); for ( int i = 0; i < Test::numThreads; i++ ) { t[ i ] = gcnew Thread( gcnew ThreadStart( Test::ThreadProc ) ); t[ i ]->Name = gcnew String( Convert::ToChar( i + 65 ),1 ); t[ i ]->Start(); if ( i > 10 ) Thread::Sleep( 300 ); } // Tell the threads to shut down, then wait until they all // finish. Test::running = false; for ( int i = 0; i < Test::numThreads; i++ ) { t[ i ]->Join(); } // Display statistics. Console::WriteLine( "\r\n {0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.", Test::reads, Test::writes, Test::readerTimeouts, Test::writerTimeouts ); Console::WriteLine( "Press ENTER to exit." ); Console::ReadLine(); return 0; }
// This example shows a ReaderWriterLock protecting a shared // resource that is read concurrently and written exclusively // by multiple threads. // The complete code is located in the ReaderWriterLock // class topic. import System.*; import System.Threading.*; import System.Threading.Thread; public class Test { // Declaring the ReaderWriterLock at the class level // makes it visible to all threads. private static ReaderWriterLock rwl = new ReaderWriterLock(); // For this example, the shared resource protected by the // ReaderWriterLock is just an integer. private static int resource = 0; private static int numThreads = 26; private static boolean running = true; private static Random rnd = new Random(); // Statistics. private static int readerTimeouts = 0; private static int writerTimeouts = 0; private static int reads = 0; private static int writes = 0; public static void main(String[] args) { // Start a series of threads. Each thread randomly // performs reads and writes on the shared resource. Thread t[] = new Thread[numThreads]; for (int i = 0; i < numThreads; i++) { t[i] = new Thread(new ThreadStart(ThreadProc)); t[i].set_Name(new String(Convert.ToChar((i + 65)), 1)); t[i].Start(); if (i > 10) { Thread.Sleep(300); } } //main // Tell the threads to shut down, then wait until they all // finish. running = false; for (int i = 0; i < numThreads; i++) { t[i].Join(); } // Display statistics. Console.WriteLine("\r\n{0} reads, {1} writes, {2} reader time-outs," + " {3} writer time-outs.", new Object[] { (Int32)(reads), (Int32)(writes), (Int32)(readerTimeouts), (Int32)(writerTimeouts) }); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); } //Test static void ThreadProc() { // As long as a thread runs, it randomly selects // various ways to read and write from the shared // resource. Each of the methods demonstrates one // or more features of ReaderWriterLock. while (running) { double action = rnd.NextDouble(); if (action < 0.8) { ReadFromResource(10); } else { if (action < 0.81) { ReleaseRestore(50); } else { if (action < 0.9) { UpgradeDowngrade(100); } else { WriteToResource(100); } } } } } //ThreadProc // Shows how to request and release a reader lock, and // how to handle time-outs. static void ReadFromResource(int timeOut) { try { rwl.AcquireReaderLock(timeOut); try { // It is safe for this thread to read from // the shared resource. Display(("reads resource value " + resource)); Interlocked.Increment(reads); } finally { // Ensure that the lock is released. rwl.ReleaseReaderLock(); } } catch (ApplicationException exp) { // The reader lock request timed out. Interlocked.Increment(readerTimeouts); } } //ReadFromResource // Shows how to request and release the writer lock, and // how to handle time-outs. static void WriteToResource(int timeOut) { try { rwl.AcquireWriterLock(timeOut); try { // It is safe for this thread to read or write // from the shared resource. resource = rnd.Next(500); Display(("writes resource value " + resource)); Interlocked.Increment(writes); } finally { // Ensure that the lock is released. rwl.ReleaseWriterLock(); } } catch (ApplicationException exp) { // The writer lock request timed out. Interlocked.Increment(writerTimeouts); } } //WriteToResource // Shows how to request a reader lock, upgrade the // reader lock to the writer lock, and downgrade to a // reader lock again. static void UpgradeDowngrade(int timeOut) { try { rwl.AcquireReaderLock(timeOut); try { // It is safe for this thread to read from // the shared resource. Display(("reads resource value " + resource)); Interlocked.Increment(reads); // If it is necessary to write to the resource, // you must either release the reader lock and // then request the writer lock, or upgrade the // reader lock. Note that upgrading the reader lock // puts the thread in the write queue, behind any // other threads that might be waiting for the // writer lock. try { LockCookie lc = rwl.UpgradeToWriterLock(timeOut); try { // It is safe for this thread to read or write // from the shared resource. resource = rnd.Next(500); Display(("writes resource value " + resource)); Interlocked.Increment(writes); } finally { // Ensure that the lock is released. rwl.DowngradeFromWriterLock(lc); } } catch (ApplicationException exp) { // The upgrade request timed out. Interlocked.Increment(writerTimeouts); } // When the lock has been downgraded, it is // still safe to read from the resource. Display(("reads resource value " + resource)); Interlocked.Increment(reads); } finally { // Ensure that the lock is released. rwl.ReleaseReaderLock(); } } catch (ApplicationException exp) { // The reader lock request timed out. Interlocked.Increment(readerTimeouts); } } //UpgradeDowngrade // Shows how to release all locks and later restore // the lock state. Shows how to use sequence numbers // to determine whether another thread has obtained // a writer lock since this thread last accessed the // resource. static void ReleaseRestore(int timeOut) { int lastWriter; try { rwl.AcquireReaderLock(timeOut); try { // It is safe for this thread to read from // the shared resource. Cache the value. (You // might do this if reading the resource is // an expensive operation.) int resourceValue = resource; Display(("reads resource value " + resourceValue)); Interlocked.Increment(reads); // Save the current writer sequence number. lastWriter = rwl.get_WriterSeqNum(); // Release the lock, and save a cookie so the // lock can be restored later. LockCookie lc = rwl.ReleaseLock(); // Wait for a random interval (up to a // quarter of a second), and then restore // the previous state of the lock. Note that // there is no time-out on the Restore method. Thread.Sleep(rnd.Next(250)); rwl.RestoreLock(lc); // Check whether other threads obtained the // writer lock in the interval. If not, then // the cached value of the resource is still // valid. if (rwl.AnyWritersSince(lastWriter)) { resourceValue = resource; Interlocked.Increment(reads); Display(("resource has changed " + resourceValue)); } else { Display(("resource has not changed " + resourceValue)); } } finally { // Ensure that the lock is released. rwl.ReleaseReaderLock(); } } catch (ApplicationException exp) { // The reader lock request timed out. Interlocked.Increment(readerTimeouts); } } //ReleaseRestore // Helper method briefly displays the most recent // thread action. Comment out calls to Display to // get a better idea of throughput. static void Display(String msg) { Console.Write("Thread {0} {1}. \r", Thread.get_CurrentThread().get_Name(), msg); } //Display }

System.Runtime.ConstrainedExecution.CriticalFinalizerObject
System.Threading.ReaderWriterLock


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 によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


ReaderWriterLock コンストラクタ
アセンブリ: mscorlib (mscorlib.dll 内)


' The complete code is located in the ReaderWriterLock ' class topic. Imports System Imports System.Threading Imports Microsoft.VisualBasic Public Class Test ' Declaring the ReaderWriterLock at the class level ' makes it visible to all threads. Private Shared rwl As New ReaderWriterLock() ' For this example, the shared resource protected by the ' ReaderWriterLock is just an integer. Private Shared resource As Integer = 0 <br /><span space="preserve">...</span><br />End Class 'Test
// The complete code is located in the ReaderWriterLock // class topic. using System; using System.Threading; public class Test { // Declaring the ReaderWriterLock at the class level // makes it visible to all threads. static ReaderWriterLock rwl = new ReaderWriterLock(); // For this example, the shared resource protected by the // ReaderWriterLock is just an integer. static int resource = 0; <br /><span space="preserve">...</span><br />}
// The complete code is located in the ReaderWriterLock // class topic. using namespace System; using namespace System::Threading; public ref class Test { public: // Declaring the ReaderWriterLock at the class level // makes it visible to all threads. static ReaderWriterLock^ rwl = gcnew ReaderWriterLock; // For this example, the shared resource protected by the // ReaderWriterLock is just an integer. static int resource = 0; <br /><span space="preserve">...</span><br />};
// The complete code is located in the ReaderWriterLock // class topic. import System.*; import System.Threading.*; import System.Threading.Thread; public class Test { // Declaring the ReaderWriterLock at the class level // makes it visible to all threads. private static ReaderWriterLock rwl = new ReaderWriterLock(); // For this example, the shared resource protected by the // ReaderWriterLock is just an integer. private static int resource = 0; <br /><span space="preserve">...</span><br />}

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 によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


ReaderWriterLock プロパティ

名前 | 説明 | |
---|---|---|
![]() | IsReaderLockHeld | 現在のスレッドがリーダー ロックを保持しているかどうかを示す値を取得します。 |
![]() | IsWriterLockHeld | 現在のスレッドがライタ ロックを保持しているかどうかを示す値を取得します。 |
![]() | WriterSeqNum | 現在のシーケンス番号を取得します。 |

ReaderWriterLock メソッド

名前 | 説明 | |
---|---|---|
![]() | AcquireReaderLock | オーバーロードされます。 リーダー ロックを取得します。 |
![]() | AcquireWriterLock | オーバーロードされます。 ライタ ロックを取得します。 |
![]() | AnyWritersSince | シーケンス番号の取得後にライタ ロックを取得したスレッドがあったかどうかを示します。 |
![]() | DowngradeFromWriterLock | スレッドのロック ステータスを、UpgradeToWriterLock を呼び出す前の状態に復元します。 |
![]() | Equals | オーバーロードされます。 2 つの Object インスタンスが等しいかどうかを判断します。 ( Object から継承されます。) |
![]() | GetHashCode | 特定の型のハッシュ関数として機能します。GetHashCode は、ハッシュ アルゴリズムや、ハッシュ テーブルのようなデータ構造での使用に適しています。 ( Object から継承されます。) |
![]() | GetType | 現在のインスタンスの Type を取得します。 ( Object から継承されます。) |
![]() | ReferenceEquals | 指定した複数の Object インスタンスが同一かどうかを判断します。 ( Object から継承されます。) |
![]() | ReleaseLock | スレッドがロックを取得した回数に関係なく、ロックを解放します。 |
![]() | ReleaseReaderLock | ロック カウントをデクリメントします。 |
![]() | ReleaseWriterLock | ライタ ロックのロック カウントがデクリメントします。 |
![]() | RestoreLock | スレッドのロック ステータスを、ReleaseLock を呼び出す前の状態に復元します。 |
![]() | ToString | 現在の Object を表す String を返します。 ( Object から継承されます。) |
![]() | UpgradeToWriterLock | オーバーロードされます。 リーダー ロックをライタ ロックにアップグレードします。 |

ReaderWriterLock メンバ
ReaderWriterLock データ型で公開されるメンバを以下の表に示します。


名前 | 説明 | |
---|---|---|
![]() | IsReaderLockHeld | 現在のスレッドがリーダー ロックを保持しているかどうかを示す値を取得します。 |
![]() | IsWriterLockHeld | 現在のスレッドがライタ ロックを保持しているかどうかを示す値を取得します。 |
![]() | WriterSeqNum | 現在のシーケンス番号を取得します。 |

名前 | 説明 | |
---|---|---|
![]() | AcquireReaderLock | オーバーロードされます。 リーダー ロックを取得します。 |
![]() | AcquireWriterLock | オーバーロードされます。 ライタ ロックを取得します。 |
![]() | AnyWritersSince | シーケンス番号の取得後にライタ ロックを取得したスレッドがあったかどうかを示します。 |
![]() | DowngradeFromWriterLock | スレッドのロック ステータスを、UpgradeToWriterLock を呼び出す前の状態に復元します。 |
![]() | Equals | オーバーロードされます。 2 つの Object インスタンスが等しいかどうかを判断します。 (Object から継承されます。) |
![]() | GetHashCode | 特定の型のハッシュ関数として機能します。GetHashCode は、ハッシュ アルゴリズムや、ハッシュ テーブルのようなデータ構造での使用に適しています。 (Object から継承されます。) |
![]() | GetType | 現在のインスタンスの Type を取得します。 (Object から継承されます。) |
![]() | ReferenceEquals | 指定した複数の Object インスタンスが同一かどうかを判断します。 (Object から継承されます。) |
![]() | ReleaseLock | スレッドがロックを取得した回数に関係なく、ロックを解放します。 |
![]() | ReleaseReaderLock | ロック カウントをデクリメントします。 |
![]() | ReleaseWriterLock | ライタ ロックのロック カウントがデクリメントします。 |
![]() | RestoreLock | スレッドのロック ステータスを、ReleaseLock を呼び出す前の状態に復元します。 |
![]() | ToString | 現在の Object を表す String を返します。 (Object から継承されます。) |
![]() | UpgradeToWriterLock | オーバーロードされます。 リーダー ロックをライタ ロックにアップグレードします。 |

Weblioに収録されているすべての辞書からReaderWriterLockを検索する場合は、下記のリンクをクリックしてください。

- ReaderWriterLockのページへのリンク