Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does `lock` (Monitor) work in .NET?

I've been wondering recently how lock (or more specific: Monitor) works internally in .NET with regards to the objects that are locked. Specifically, I'm wondering what the overhead is, if there are 'global' (Process) locks used, if it's possible to create more of those global locks if that's the case (for groups of monitors) and what happens to the objects that are passed to lock (they don't seem to introduce an extra memory overhead).

To clarify what I'm not asking about: I'm not asking here about what a Monitor is (I made one myself at University some time ago). I'm also not asking how to use lock, Monitor, how they compile to a try/finally, etc; I'm pretty well aware of that (and there are other SO questions related to that). This is about the inner workings of Monitor.Enter and Monitor.Exit.

For example, consider this code executed by ten threads:

for (int i=0; i<1000; ++i) 
{
    lock (myArray[i])
    {
        // ...
    }
}
  • Is it bad to lock a thousand objects instead of one? What is impact in terms of performance / memory pressure?
  • The underlying monitor creates a wait queue. Is it possible to have more than one wait queue and how would I create that?
like image 936
atlaste Avatar asked Jan 10 '14 09:01

atlaste


People also ask

How does lock works in C#?

The lock statement acquires the mutual-exclusion lock for a given object, executes a statement block, and then releases the lock. While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and waits until the lock is released.

What is a monitor lock?

A lock typically prevents more than one entity from accessing a shared resource. Each object in the Java language has an associated lock, also referred to as a monitor, which a thread obtains by using a synchronized method or block of code.

How is lock different from Monitor in C#?

Both Monitor and lock provides a mechanism that synchronizes access to objects. lock is the shortcut for Monitor. Enter with try and finally. Lock is a shortcut and it's the option for the basic usage.

What is lock in .NET core?

The Lock statement is used in threading, that limit the number of threads that can perform some activity or execute a portion of code at a time. Exclusive locking in threading ensures that one thread does not enter a critical section while another thread is in the critical section of the code.


2 Answers

Monitor.Enter is not a normal .NET method (can't be decompiled with ILSpy or similar). The method is implemented internally by the CLR, so strictly speaking, there is no one answer for .NET as different runtimes can have different implementations.

All objects in .NET have an object header containing a pointer to the type of the object, but also an SyncBlock index into a SyncTableEntry. Normally that index is zero/non used, but when you lock on the object it will contain an index into the SyncTableEntry which then contains the reference to the actual lock object.

So locking of thousands of objects will indeed create a lot of locks which is an overhead.

The information I found was in this MSDN article: http://msdn.microsoft.com/en-us/magazine/cc163791.aspx

like image 73
Anders Abel Avatar answered Oct 05 '22 22:10

Anders Abel


Here's a good place to read about monitors, memory barriers etc.

EDIT

Screen shot from the page in case page become down in future: enter image description here

like image 33
SOReader Avatar answered Oct 05 '22 21:10

SOReader