Can someone explain the difference between:
- lock (someobject) {}
- Using Mutex
- Using Semaphore
- Using Monitor
- Using Other .Net synchronization classes
I just can't figure it out. It seems to me the first two are the same?
Can someone explain the difference between:
I just can't figure it out. It seems to me the first two are the same?
Great question. I maybe wrong.. Let me try.. Revision#2 of my orig answer.. with a little bit of more understanding. Thanks for making me read :)
lock(obj)
Monitors
Using a lock or monitor is useful for preventing the simultaneous execution of thread-sensitive blocks of code, but these constructs do not allow one thread to communicate an event to another. This requires synchronization events, which are objects that have one of two states, signaled and un-signaled, that can be used to activate and suspend threads. Mutex, Semaphores are OS-level concepts. e.g with a named mutex you could synchronize across multiple (managed) exes (ensuring that only one instance of your application is running on the machine.)
Mutex:
Semaphores (hurt my brain).
As stated in ECMA, and as you can observe from Reflected methods the lock statement is basically equivalent to
object obj = x;
System.Threading.Monitor.Enter(obj);
try {
…
}
finally {
System.Threading.Monitor.Exit(obj);
}
From the aforementioned example we see that Monitors can lock on objects.
Mutexe's are useful when you need interprocess synchronization as they can lock on a string identifier. The same string identifier can be used by different processes to acquire the lock.
Semaphores are like Mutexes on steroids, they allow concurrent access by providing a maximum count of concurrent access'. Once the limit is reached the semaphore starts blocking any further access to the resource until one of the callers releases the semaphore.
Re "Using Other .Net synchronization classes"- some of the others you should know about:
There are also more (low overhead) locking constructs in CCR/TPL (the Parallel Extensions CTP) - but IIRC, these will be made available in .NET 4.0
An additional caveat for locking on any shared Mutex you've identified with a string ID is that it will default to a "Local\" mutex and will not be shared across sessions in a terminal server environment.
Prefix your string identifier with "Global\" to ensure that access to shared system resources is properly controlled. I was just running into a whole heap of problems synchronizing communications with a service running under the SYSTEM account before I realized this.
I would try to avoid lock() and Mutex, Monitor if you can...
Check out the new namespace System.Collections.Concurrent in .NET 4
It has some nice thread-safe collection classes
http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx
ConcurrentDictionary rocks! no manual locking anymore for me!