|< Day Day Up >|
22.11 Synchronizing Resource Access Using Reader/Writer Locks
In this situation, the normal technique is to use a ReaderWriterLock . As with mutexes , synchronization is performed against the lock itself rather than against the data.
You first need to instantiate the lock:
ReaderWriterLock rw = new ReaderWriterLock();
If some code needs to read the protected data, the code looks like this:
rw.AcquireReaderLock(500); // protected code here rw.ReleaseReaderLock();
Note that the AcquireReaderLock() method takes an int parameter which indicates the maximum time in milliseconds that you want to wait for the lock. In this code, we specified half a second. As with other thread synchronization primitives, an ApplicationException is thrown if this period times out. You can pass a TimeSpan instead of an int to this method, but you must pass in a parameter: There is no default no-timeout overload for this method. If you want the thread to wait indefinitely for the lock, then you should pass “1 as an int .
If, on the other hand, some code needs to write to the protected data, you code this:
rw.AcquireWriterLock(500); // protected code here rw.ReleaseWriterLock();
AcquireWriterLock() has exactly the same semantics as AcquireReaderLock() .
The point of ReaderWriterLock , of course, is that you only need to synchronize access to some data if at least one thread is actually writing to the data. It is not possible for thread synchronization bugs to occur if it's simply a case of multiple threads reading data at the same time because the data is always in a consistent state. ReaderWriterLock is designed to take account of this optimization: A thread that has a reader lock never blocks any other threads that merely want to acquire reader locks. However, if a thread acquires a writer lock, then it blocks all other threads until the writer lock is released. Note that writer locks also take priority, in the sense that if any thread is even waiting for a writer lock, the CLR does not grant any more threads reader locks: The writer lock gains access first. This process ensures that a writer lock doesn't get blocked out for a long time while reader threads ask for reader locks.
In terms of overhead, a ReaderWriterLock is slower than a monitor. However, if many threads are likely to want to read data that is only rarely written to, then you gain performance benefits from using it because in general threads are blocked less often. This point is especially true if the operations that involve reading the data are lengthy operations.
|< Day Day Up >|