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 (The locking implementation)
- Synchronize Keyword (Acquiring the lock)
- Object Monitor Methods (Signalling methods)
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);
}
}