lock vs. MethodImplOptions.Synchronized [Kit George]
A BCL Website customer (Michael) recently asked:
Is there any difference in the jitted code between using the Attribute System.Runtime.CompilerServices.MethodImplAttribute( MethodImplOptions.Synchronized ) and using a lock(this) {...} in the method body? The IL code is different. What you suggest to use for synchronizing complete methods?
Michael, both options are functionally equivalent. However, for most cases we recommend neither of them, for the following reasons.
We strongly discourage the use of lock(this). Since other, completely unrelated code can choose to lock on that object as well, you could find yourself trying to debug a hard-to-find deadlock or throughput problem. Instead, either lock on the object you’re sharing across threads (assuming you know its code never tries to lock on it for unrelated reasons), or create a private dummy object to lock on.
A given piece of IL may generate different code from release to release, or between JIT and NGEN. Anything we tell you now—or you find out by disassembly—might not be valid in the next release.
Comments
Anonymous
January 20, 2004
OK, I can see how something like Hashtable shouldn't use lock(this). Even though I firmly believe that "completely unrelated" code has no buisness using lock() on Hashtable instances, there is no way to prevent people from doing this.
But what's wrong with using lock(this) in an internal type that's never exposed to the outside world? If you don't know what your own code is doing then you have bigger problems than potential deadlocks.Anonymous
April 21, 2004
BCLTeam,
There is a discussion of this issue also at http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_20926988.html. There, someone states:
<quote>
MethodImplOptions.Synchronized: Specifies the method can be executed by only one thread at a time.
The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock
So: if you lock an object, all other threads that need to access THIS PARTICULAR OBJECT will wait, until the other object finishes. However if you mark a method as Synchronized, THIS PARTICULAR METHOD will not be executed at more than one thread. Lock secures the object, Synchronized secures the method
</quote>
This explanation appears different from your explanation (which, from what I can see, is stating that MethodImplOptions.Synchronized locks the whole object rather than just the specific method).
Or, stating it in other terms, what is the answer to the following question:
* Assume two instance methods (MethodA and MethodB) in a class both have the MethodImplOptions.Synchronized attribute. Does the use of the attribute stop:
a) MethodA executing twice at the same time.
b) MethodB executing twice at the same time.
c) MethodA and MethodB executing (once each) at the same time.
The discrepancy (in my mind) is about the c) case.
Thanks
MatthewAnonymous
May 19, 2004
What about using System.Threading.Thread.MemoryBarrier(); as Brad Abrams discusses below?
http://blogs.msdn.com/brada/archive/2004/05/12/130935.aspxAnonymous
January 18, 2009
PingBack from http://www.keyongtech.com/4979830-simplest-thread-safe-patternAnonymous
January 21, 2009
PingBack from http://www.keyongtech.com/658806-how-did-it-dead-lock