1. Overview


A monitor is a structured way of combining synchronization and data, encapsulating data, methods, and synchronization in a single modular package in the same way that a class encapsulates data and methods.

More generally, this combination of methods, mutual exclusion locks, and condition objects is called a monitor.

Why do we need monitor?

The traditional way of seperating synchronization and data is cumbersome when implementing, for example:

mutex.lock(); 
try {
	queue.enq(x) 
} finally {
	mutex.unlock(); 
}

If the queue is bounded, then we may be freezed at line 3 forever, since perhaps no other thread can operate on the queue.

A more sensible approach is to allow each queue to manage its own synchronization. The queue itself has its own internal lock, acquired by each method when it is called and released when it returns.

2. Monitor Types


The different decisions on whether the signaler or the signalee will hold the lock after the CV is signaled result in different types of monitors.

Hoare - Signaler Yields

  1. If thread A signals a condition variable CV on which there are threads waiting, one of the waiting threads, say B, will be released immediately.
  2. Before B can run, A is suspended and its monitor lock is taken away by the monitor.
  3. Then, the monitor lock is given to the released thread B so that when it runs it is the only thread executing in the monitor.
  4. Sometime later, when the monitor becomes free, the signaling thread A will have a chance to run.

In summary, the signaling thread will be blocked until the signaled thread released the lock.

<aside> 💡 Merits

  1. B enters the monitor earlier than A did, and hence A yields the monitor to a senior thread, who might has a more urgent task to perform.
  2. B is free from worrying that the event may be changed between the time the CV is signaled and the time B runs again. </aside>