views:

404

answers:

6

Please explain what are the main differences and when should I use what.
The focus on web multi-threaded applications.

+4  A: 

lock allows only one thread to execute the code at the same time. ReaderWriterLock may allow multiple threads to read at the same time or have exclusive access for writing, so it might be more efficient. If you are using .NET 3.5 ReaderWriterLockSlim is even faster. So if your shared resource is being read more often than being written, use ReaderWriterLockSlim. A good example for using it is a file that you read very often (on each request) and you update the contents of the file rarely. So when you read from the file you enter a read lock so that many requests can open it for reading and when you decide to write you enter a write lock. Using a lock on the file will basically mean that you can serve one request at a time.

Darin Dimitrov
so what you are saying is that if first thread reads a value that is inside lock{} no other thread can read it in the same time?
kenny
Exactly, `lock` will allow one and only one thread to execute the body of the lock statement.
Darin Dimitrov
"so it might be more efficient": but probably won't be and your code will be more complex. It should be reserved for niche cases.
Richard
Yes, performing stress testing and measuring is a good way to know for sure.
Darin Dimitrov
If you *just* wish to cache a file in memory, it is likely that the Asp.net cache would be a better solution, with a refresh policy setup so your object is removed from the cache when the file changes.
Ian Ringrose
BTW ReaderWriterLock is deprecated in favour of ReaderWriterLockSlim. If you chose to use one of them, use the latter one.
Stupid question: If the read lock allows concurrent access to a resource, why do I have to use any kind of locking? Could I not allow reads without any locking?
flq
@Frank, this will depend on whether the shared resource allows concurrent readers. If it does then of course you don't need to lock. But remember that even basic things like enumerating a collection is not thread safe.
Darin Dimitrov
+2  A: 

Consider using ReaderWriterLock if you have lots of threads that only need to read the data and these threads are getting blocked waiting for the lock and and you don’t often need to change the data.

However ReaderWriterLock may block a thread that is waiting to write for a long time.

Therefore only use ReaderWriterLock after you have confirmed you get high contention for the lock in “real life” and you have confirmed you can’t redesign your locking design to reduce how long the lock is hold for.

Also consider if you can stored the shared data in a database and let it take care of all locking, this is a lot less likely to give you hard to track down bugs, iff a database is fast enough for your application.

In some cases you may also be able to use the Aps.net cache to handle shared data, and just remove the item from the cache when the data changes. The next read can put a fresh copy in the cache.

Remember

"The best kind of locking is the locking you don't need (i.e. don't share data between threads)."

Ian Ringrose
+2  A: 
Richard
+1 for "The best kind of locking is the locking you don't need (i.e. don't share data between threads)."
Ian Ringrose
+1  A: 

ReaderWriterLock allows you to have multiple threads hold the ReadLock at the same time... so that your shared data can be consumed by many threads at once. As soon as a WriteLock is requested no more ReadLocks are granted and the code waiting for the WriteLock is blocked until all the threads with ReadLocks have released them.

The WriteLock can only ever be held by one thread, allow your 'data updates' to appear atomic from the point of view of the consuming parts of your code.

The Lock on the other hand only allows one thread to enter at a time, with no allowance for threads that are simply trying to consume the shared data.

ReaderWriterLockSlim is a new more performant version of ReaderWriterLock with better support for recursion and the ability to have a thread move from a Lock that is essentially a ReadLock to the WriteLock smoothly (UpgradeableReadLock).

CuriousCoder
A: 

I would suggest looking though http://www.albahari.com/threading/ - part three talks about ReaderWriterLockSlim (which you want to use instead of ReaderWriterLock).

Egil Hansen
+1  A: 

ReaderWriterLock/Slim is specifically designed to help you efficiently lock in a multiple consumer/ single producer scenario. Doing so with the lock statement is possible, but not efficient. RWL/S gets the upper hand by being able to aggressively spinlock to acquire the lock. That also helps you avoid lock convoys, a problem with the lock statement where a thread relinquishes its thread quantum when it cannot acquire the lock, making it fall behind because it won't be rescheduled for a while.

Hans Passant