Diagram on thread states with regards to ObjectMonitors

The Monitor-Based Synchronisation is the simplest, often fastest and easiest to use Synchronisation construct in Java.
However, they lack finer grain control compared to explicit locks

  • only have a single wait set
  • both entry and wait sets are unordered/unfair
  • cannot be interrupted

It is a system comprising of 3 things:

Monitors help provide the underlying implementation for synchronisation, and the synchronized keyword and object monitor methods are used to interface with the monitor!

Sample Code

class Main {
	public static void main(String[] args) {
	Counter counter = new Counter(); 
	
	// Thread 1 - waits for count to reach 5
	new Thread(() -> {
	    counter.waitUntilCount(5);
	}).start();
	
	// Thread 2 - increments the counter
	new Thread(() -> {
	    for (int i = 0; i < 5; i++) {
	        counter.increment();
			try { Thread.sleep(500); } catch (InterruptedException _e) {}
	    }
	}).start();
	}
}
 
class Counter {
    private int count = 0;
    
    // SYNCHRONIZED - acquires the monitor lock
    public synchronized void increment() {
        count++;
        this.notify(); // OBJECT MONITOR METHOD - wake up waiting thread to check target
		// End of the synchronized block, lock is realeased
    }
    
    // SYNCHRONIZED - acquires the monitor lock
    public synchronized void waitUntilCount(int target) {
        while (count < target) {
            // OBJECT MONITOR METHOD - release lock and wait to be notified
			try { this.wait(); } catch (InterruptedException _e) {}
        }
        System.out.println("Count reached: " + count);
    }
}