In the previous article, we talked about “Introduction to Monitor Class In C#”. So, in this article, we will take a detailed look at the Monitor class.

The Monitor class is a hybrid thread synchronization construct. It provides a mutual exclusive lock with supporting spinning, thread ownership, and recursion.

Hybrid Synchronization Constructs

Hybrid Synchronization Constructs are the combining the user-mode synchronization constructs and kernel-mode thread synchronization constructs.

The user-mode synchronization constructs are application level and faster than the kernel-mode synchronization constructs. Because it uses special hardware-level instructions; which it makes faster.

The user-mode synchronization constructs are:

Using user-mode constructs has some disadvantages:

The kernel-mode synchronization constructs are provided by the Windows operating system. The threads call functionalities are implemented at the level of the operating system kernel. But the advantage of this mode is when a thread wants to acquire a resource that another thread has, Windows blocks the thread, and when a resource becomes available, resumes the thread again, so the Windows throughs that achieve not wasting the CPU time.

Also, in case a thread holding the construct and another one is waiting for the construct, it might be blocked forever. Well, it is called deadlock, which wastes only memory (better than livelock because livelock wastes both CPU and memory).

The kernel-mode synchronization constructs are:

As a result of these, preferable to use fast and non-blocking constructs. This is where Hybrid Synchronization Constructs come in!

User-mode synchronization constructs are fast and non-blocking. It is very effective, but in the case of racing/competition (needs blocking + efficiency) would be better to use Kernel-mode synchronization constructs. Also, note that the Kernel mode can block (stop) the threads, but the User-mode can only spin in case of the blocking (for that reason, they are non-blocking, on the other hand they help us to reuse threads).

Hybrid synchronization constructs combine the user-mode and kernel-mode constructs and provide more effective constructs.

How Monitor Class Works Internally?

How Monitor Class Works Internally

As we see from the image above, the image contains the Managed heap and CLR’s Array of Sync Blocks. Well, when CLR allocates the object instance in a heap, it has some fields. One of them is type object pointer and another one is sync block index. The sync block index belongs to thread synchronization, and it contains an integer index in the array of sync blocks. So, CLR also, for efficiency, creates the array of sync blocks (in a native heap) that provides association with type through the index number.

Let’s think that we constructed an object (initialized). So, when the Object is constructed its sync block index assigns -1 by default. Which means that there is no reference to any sync block. Well, let’s assume that we want to use that object as an input parameter in Monitor.Enter method. So, in this case, CLR will find the free index in CLR’s array of sync blocks, occupy it, and then set the index into the object sync block (it would be on the fly reference).

In the case of the Monitor.Exit method, the used object sync block index will assign -1. And CLR’s array of sync blocks will be free. As we see the sync block index looks like a conditional flag (indicates the locked or not locked).

There are Some Problems With the Monitor Class

When using a monitor, there are some significant problems. So, be careful when using the Monitor class.

If you want to learn more, you can check out the book "CLR via C# by Jeffrey Richter".

Stay tuned!