How is the monitor used for synchronization?
Tags: beginners, programming, backend, synchronization
Published: 2023-03-16 04:23:07

#**Monitor**

- Ensures mutual exclusion
- Allows threads to wait based on conditions

###When is it used?

- When only one thread should be executing at a time
- When collaboration between multiple threads is needed

###Components of the monitor

**- Mutex**: A device that ensures mutual exclusion in critical sections. A thread must acquire a mutex lock to enter a critical section. If a thread cannot acquire the mutex lock, it goes into a waiting state in the queue. When a thread holding the mutex lock releases it, one of the waiting threads in the queue is selected to execute.

**- Condition variables**: Have a waiting queue. Where threads wait for a condition to be met in a waiting state.

###Operations on condition variables:

- wait: The thread puts itself in the waiting queue of the condition variable and goes into a waiting state.
- signal: Wakes up one of the threads waiting in the waiting queue.
- broadcast: Wakes up all threads waiting in the waiting queue.


```
acquire(m) // Acquire the lock of the monitor
while(!p) { // Check the condition
	wait(m, cv); // If the condition is not met, wait
}
...
signal(cv2); --OR-- broadcast(cv2); //cv2 can be the same as cv
release(m); // Release the lock of the monitor

```
**When a thread enters the waiting queue, it must release the lock.**

###Two queues

**- Entry queue:** The queue of threads waiting **to enter the critical section.** Managed by the mutex.
**- Waiting queue:** The queue of threads waiting for a **condition** to be met. Managed by the condition variable.

### Bounded producer/consumer problem:

The producer creates goods and fills them in a buffer, while the consumer consumes the goods.

Problem scenario 1: The producer keeps creating goods, but the buffer is full and there is no room left.

Problem scenario 2: The consumer tries to consume goods, but the buffer is empty and there is nothing to consume.



```
global volatile Buffer q;
global Lock lock;
global CV fullCV;
global CV emptyCV;
-------------------------------------------------------
public method producer() {
	while(true) {
		task myTask = ...'

		lock.acquire(); 
		// A mutex lock is required to enter the CV. If there is no lock, enter the entry queue and wait.

		while(q.isFull()) {
			wait(lock, fullCV); // Check if the buffer is full. If it is full, wait in the waiting queue.
		}
	
		q.enqueue(myTask);

		signal(emptyCV); --or-- broadcast(emptyCV);

		lock.release();
		}
	}

--------------------------------------------------------

public method consumer() {
	while(true) {
		lock.acquire();
		// The producer and consumer compete for one lock.
		while(q.isEmpty()) {{
			wait(lock, emptyCV);
		} // Always wait in the while loop so that when awakened, it can check if the condition is met.
			// If the buffer is empty, wait in the waiting queue.
		myTask = q.dequeue();

		signal(fullCV); --or-- broadcast(fullCV);

		lock.release();

		doStuff(myTask);
	}
}

```
###What is a Java monitor?

In Java, every object has an internal monitor.

The mutual exclusion functionality of the monitor is used with the synchronized keyword.

Java monitors have only one condition variable.

**Three operations of the Java monitor:**

- wait
- notify(signal)
- notifyAll(broadcast)



**This posting is just a study note which was written after watching youtube videos in Korean.**
[ https://youtu.be/Dms1oBmRAlo](youtube link)