Synchronization by lock and Monitor statements in C#

Working through enterprise applications has various challenges, among them, multi-threading stands out. Nowadays, all applications tend to use all capabilities of modern hardware, especially CPUs in our case. Performing several jobs simultaneously by multiple threads brings about more advantages for us like high processing speed, however, without having enough knowledge on this matter, our application outcomes may go toward deterioration.

Fighting for grabbing resources not only belongs to real-life environments but also is the truth on the wire. In such scenarios, we have a situation that must be addressed, otherwise, something undoubtedly happens which commonly called a race condition. It means an undesirable situation that occurs when a device or system attempts to perform two or more operations in a time.

Our duty as a programmer is to establish certain policies in order to bring fairness and balance among resources and consumers. By doing this, the mess would be wrapped up.


lock statement

It ensures that only one thread can enter a critical section of codes. Other threads that try to be the owner of the `lock` would be suspended until the first thread releases the `lock`.

As you can see, the `lock` guarantees that only one thread could increment the value of the `counter`. The `lockerObject` is a synchronizing object that can be locked by only one thread at a time.

Choosing the right synchronization object

Also, you can use `this` object as a synchronizing object. For example:

As mentioned, locking in this way has a serious issue that is not encapsulating the locking logic and can prone to deadlock.

Briefly, the most reliable way for choosing a synchronizing object is to consider a private object in the class by which you can have precise control over it.

Under the hood

There is a vulnerability in this code. If an exception is being thrown between `Monitor.Enter()` and `try` due to for example `OutOfMemoryException` or the thread is being aborted, also if `lock` is being taken, it is never released because the thread never gets into the `try` block and causes leaked lock.

This danger has been fixed in C# 4.0. the following overload is added to `Monitor.Enter`.

Eventually, from C# 4.0 onward the `lock` statement is translated to the following code. As you see, the vulnerability that we saw before has healed.

In short, the `lock` is shorthand for utilizing the `Monitor` statement. Let’s take a closer look at it.

The `Monitor` statement

The `Monitor` never be released unless the owner of `Monitor` must pass to `Exit`. Therefore, if you pass an object to `Exit` which is not the owner of the Monitor, you will get the `SynchronizationLockException` exception with the message “Object synchronization method was called from an unsynchronized block of code.

Lock on a Reference Type, Not a Value Type

The below codes show the point:

If we box the `locker` then passed through the `Enter` the above exception never happens. For example:

Monitor Sample

The below code lunches ten tasks, each of which sleeps for 200 milliseconds and increments the value of the `counter` variable. The critical section enclosed by `Enter` and `Exit` methods so that Our program works well and displays the expected result on the screen.

Monitor static methods


Here is not the end of our story; in the next post, we will go through some practical samples and see how `lock` is used in conjunction with other `Monitor` methods for a more advanced form of thread coordination.

Next mission

A self-motivated .Net developer with a love of learning.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store