Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: March 26, 2025
In this tutorial, we’ll learn what a monitor is and how we use it in Java.
A monitor is a synchronization mechanism that allows threads to have:
Why is this feature called “monitor”? Because it monitors how threads access some resources.
Monitors formally became subject of interest in the early ’70s in the paper written by P.B. Hansen named Shared Classes. After that, C.A.R. Hoare wrote the paper Monitors – an Operating System Structuring Concept where he developed the concept of Monitors even further. The paper introduced a form of synchronization and proposed a model of implementation using semaphores.
Monitors provide three main features to the concurrent programming:
A critical section is a part of the code that accesses the same data through different threads.
In Java, we use the synchronized keyword to mark critical sections. We can use it to mark methods (also called synchronized methods) or even smaller portions of code (synchronized statements).
There are opposed opinions about which approach to favor – method synchronization is usually the recommended simpler approach, while the synchronized statements could be a better choice from the security point of view.
In Java, there’s a logical connection between the monitor and every object or class. Hence, they cover instance and also static methods. Mutual exclusion is accomplished with a lock associated with every object and class. This lock is a binary semaphore called a mutex.
Java’s implementation of a monitor mechanism relies on two concepts – the entry set and the wait set. In literature, authors use a building and exclusive room analogy to represent the monitor mechanism. In this analogy, only one person can be present in an exclusive room at a time.
So, in this analogy:
When the person wants to enter the exclusive room, he first goes to the hallway (the entry set) where he waits for a scheduler. Therefore, the scheduler will pick the person and send him to the exclusive room.
Schedulers in JVMs use a priority-based scheduling algorithm. In case two threads have the same priority, the JVM uses the FIFO approach.
Hence, when the scheduler picks the person, he enters the exclusive room. It could be that some specific situation is happening in this room, so that person needs to go out and wait for the exclusive room to become available again. Therefore, that person will end up in the waiting room (the wait set). Consequently, the scheduler will schedule this person to enter an exclusive room later.
Also, it’s important to mention the steps that threads go through during this process, using the same analogy:
Luckily, Java does most of the work in the background, and we don’t need to write semaphores when we’re dealing with multi-threaded applications. Therefore, the only thing we need to do is wrap our critical section with the synchronized keywords and it momentarily becomes a monitor region.
wait() and notify() are key methods in Java used in synchronized blocks that enable collaboration between threads.
wait() orders the calling thread to release the monitor and go to sleep until some other thread enters this monitor and calls notify(). Also, notify() wakes up the first thread that called wait() on the specific object.
In this article, we discussed the concept of a monitor and then explained its implementation in Java.
As we learned, it’s the core synchronization mechanism that’s hidden behind the synchronized keyword. It relies on the wait set and entry set, and we explained how this works through a simple analogy.
We also mentioned the usage of wait and notify methods.