Partilhar via


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
    Matthew

  • Anonymous
    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.aspx

  • Anonymous
    January 18, 2009
    PingBack from http://www.keyongtech.com/4979830-simplest-thread-safe-pattern

  • Anonymous
    January 21, 2009
    PingBack from http://www.keyongtech.com/658806-how-did-it-dead-lock