Operating Systems

Monitors

A language-level construct: a mutex plus condition variables bundled with the data.

Level: intermediate

What is it?

A monitor is a concurrency abstraction that encapsulates shared state, operations on that state, and synchronization. In common designs, only one thread executes a monitor procedure at a time, and condition variables let threads wait until a state predicate may become true.

Why does it matter?

Encapsulation keeps the locking discipline close to the data invariant. This reduces the chance that a caller forgets to acquire a lock or changes state through an unsafe access path.

Mental model

Think of the monitor as a guarded room containing both the resource and its rules. Callers request operations rather than manipulating the shared state directly; condition variables provide a queue for threads waiting for a particular condition.

How it works

  • Monitor procedures protect the shared invariant according to the monitor's mutual-exclusion rules.
  • Condition variables represent waiting for a predicate, not a durable count of events.
  • A wait generally releases the monitor lock while sleeping and reacquires it before returning.
  • Because another thread may change the state before a woken thread proceeds, predicate checks belong in a loop.
  • Monitor semantics vary by language and runtime, so confirm whether signaling hands off immediately or merely makes a waiter runnable.

Steps

  • A bounded queue stores a mutex-protected queue and a notEmpty condition variable.
  • A consumer acquires the monitor and loops while the queue is empty, waiting on notEmpty.
  • A producer adds an item while holding the monitor and signals notEmpty.
  • The consumer wakes, reacquires the monitor, rechecks the predicate, and removes the item.

Real-world usage

  • Designing thread-safe classes with a clear state boundary.
  • Implementing queues, caches, and resource managers.
  • Choosing between monitor-style abstractions and lower-level semaphore protocols.

Common mistakes

  • Exposing mutable monitor state outside the synchronization boundary.
  • Using a single if before a condition wait rather than rechecking the predicate.
  • Assuming every language implements condition-variable signaling with identical scheduling semantics.

Interview questions

How does a monitor differ from a bare mutex?

A monitor packages shared state and operations with synchronization, while a mutex is a lower-level primitive that callers must apply consistently.

Why should code recheck a condition after a monitor wait?

The state may have changed before the thread reacquires the lock, or the wait may return spuriously; the predicate must still be true.

Prerequisites

Related concepts

Continue learning

Browse the full computer science library