lock(obj){
}
is similar to
Monitor.Enter(obj)
try{
.....
}
finally{
Monitor.Exit(obj)
}
It is considered a better practice to lock on an object internal to your class rather than on the class itself, which is externally exposed.
Limitation of Monitors
1. They only provide synchronization based on exclusive locking. In other words, a monitor cannot permit access to more than one thread at a time. This is true even when a set of threads are only attempting to perform read operations. This limitation can lead to inefficiencies in a scenario in which there are many read operations for each write operation.
1. Shared locking using ReaderWriterLock
The ReaderWriterLock class allows you to design a synchronization scheme which employs shared locks together with exclusive locks. This makes it possible to provide access to multiple reader threads at the same time, which effectively reduces the level of blocking. The ReaderWriterLock class also provides exclusive locking for write operations so you can eliminate inconsistent reads.
a. The reading thread can acquire a shared lock using method AcquireReaderLock
b. The writing thread can acquire an exclusibe lock using method AcquireWriterLock . Once an exclusive lock is acquired, all other reader threads and writer threads will be blocked until this thread can complete its work and call ReleaseWriterLock.
c. What would happen if a single thread calls AcquireWriterLock more than once before calling ReleaseWriterLock? Your intuition might tell you that this thread will acquire an exclusive lock with the first call to AcquireWriterLock and then block on the second call. Fortunately, this is not the case.
The ReaderWriterLock class is smart enough to associate exclusive locks with threads and track an internal lock count. Therefore, multiple calls to AcquireWriterLock will not result in a deadlock. However, this issue still requires your attention because you must ensure that two calls to the AcquireWriterLock method from a single thread are offset by two calls to the ReleaseWriterLock method. If you call AcquireWriterLock twice and only call ReleaseWriterLock once, you haven't released the lock yet.
d. Note that it is not possible for any single thread to hold both a shared lock and an exclusive lock at the same time. However, it is not uncommon that a thread will need to obtain a shared lock at first and then later escalate to an exclusive lock to perform write operations. The key point about using the ReaderWriterLock class is that a thread should never call AcquireReaderLock and then follow that with a call to AcquireWriterLock. If you do this, your call to AcquireWriterLock will block indefinitely. Instead, after calling AcquireReaderLock you should call UpgradeToWriterLock to escalate from a shared lock to an exclusive lock, as shown here:
// Acquire shared lock
lock.AcquireReaderLock(Timeout.Infinite)
// Escalate shared lock to exclusive lock
lock.UpgradeToWriterLock(Timeout.Infinite)
The key point is that a call to UpgradeToWriterLock doesn't lock down your data.
Summary of
http://msdn.microsoft.com/en-us/magazine/cc188722.aspx
http://msdn.microsoft.com/en-us/magazine/cc163846.aspx
No comments:
Post a Comment