Monitors

In my previous post we spoke about locks and resource synchronization. A Monitor also provides a similar set of actions to a lock, but the syntactic sugar slightly differs from locks. They allow a program to ensure only one thread at a time can access a particular object. Rather than controlling a statement or block of code, as the lock keyword does, the atomic code is enclosed in calls of the Monitor.Enter and Monitor.Exit. The Enter and Exit take a reference to an object which is used as the lock. Below program shows sharedTotalLock object used as lock for the update of sharedTotal value.

When lock keyword is used and if atomic code enclosing it throws exception it releases the lock automatically whereas for monitor programmer need to explicitly exit the lock. Below represents the snippet of code where the atomic code which might throw an exception is enclosed in try and Montior.Exit is enclosed in the atomic code. An additional Monitor.Exit is needed in finally block in the event the atomic code throws an exception.

Difference between Monitor and Lock:

A program that uses the lock keyword has no way to check whether or not it will be blocked when it tries to enter the locked segment of the code. If, however a monitor is used, the program can use TryEnter method which attempts to enter the code controlled by the lock. If this is not possible because the lock object is in use, the TryEnter method returns false. Below shows code snippet which uses TryEnter method.

Interlocked operations:

We saw in earlier examples when multiple tasks share the resource, it must be protected by a lock. If the atomic code is a simple operation of adding and decrementing the total, there is a better way of achieving thread safe access to the contents of a variable, which is to use the Interlocked class. It provides thread safe operations that can be performed on a variable including increment, decrement, swap and add. Below is the example of getting the sum of the contents of the array when multiple tasks are used by using Interlocked class.

Deadlocks in multi-threaded code:

The following program contains two methods and two lock objects. The methods use lock objects in different order so that each task gets a lock object each, and then waits for the other lock object to become free. When the program run, the two methods are called one after another. This program runs to completions as the methods are executed sequentially.

 

Below program shows code where the methods controlling the lock objects are performed by tasks. The tasks in this case never completes. Each task is waiting for the others lock object, and neither can continue. You will not see the program error but will use up the entire CPU memory just like an infinite loop does. They just sit in the memory unable to do anything

GitHub:Monitors&DeadLocks

#Day3Of100DaysOfCode

Last modified: October 23, 2019

Author

Comments

Write a Reply or Comment

Your email address will not be published.