Better monitors for Java

A Hoare-style monitor package for multithreaded programming in Java

Multithreaded programming is challenging but unavoidable, which is why you need the best tools and techniques for doing it safely. In this article Theodore S. Norvell introduces the conceptual underpinnings of Hoare-style monitors (such as the use of exclusive access, conditions, and assertions) then presents his own Java-based monitor package that automates assertion checking during execution.

It is all too easy to write unsafe multithreaded Java code, in part because the language's notify() and wait() methods can be difficult to use correctly. In 1974, Tony Hoare proposed the concept of monitors for designing and reasoning about objects that are shared between multiple threads. The key property of these "Hoare-style" monitors is that threads can wait until some specific assertion about the monitor's state is true and be guaranteed that it is still true after the thread has been awakened.

In this article, I describe an open source Java class library that supports the monitor concept much as Hoare originally proposed it. As I will demonstrate, object-oriented technology makes it possible to improve on Hoare's concept by making assertions -- which are traditionally stated as comments and then repeated in if statements and assert statements -- executable objects. This approach reduces redundant coding and automates assertions checking during execution.

I'll start by explaining why multithreaded programming is as unavoidable as it is challenging, then introduce you to the use of exclusive access, conditions and assertions in Hoare-style monitors. See the Resources section to download the Java-based monitors package.

The case for Hoare-style monitors

Three factors contribute to the ubiquity of multithreaded software, and thus the need for monitors:

  1. Responsive, interactive software. To be responsive, interactive software must perform tasks that take more than a few tens of milliseconds on threads other than the GUI event thread.
  2. Multiprocessor, multicore and simultaneous multithreading (hyper-threading) hardware. Computationally intensive applications must run with multiple threads to use more than a fraction of the capability of modern hardware.
  3. Distributed computing. Distributed architectures often demand that applications deal with multiple requests simultaneously. For example, RMI invocations each run on their own thread.

Coordinating the activities of two or more threads can be very tricky and can be a source of latent defects in multithreaded code. Testing is ineffective because tests may not reveal race conditions. As software engineers we must equip ourselves with the intellectual and software tools to design correct multithreaded applications.

Monitoring multithreaded access

In the 1970s Edsger Dijkstra, Per Brinch Hansen and C.A.R. Hoare developed the idea of the monitor: an object that would protect data by enforcing single-threaded access. Only one thread at a time would be allowed to execute code within the monitor, making monitors islands of single-threaded calm in a turbulent sea of multithreadedness. Confining thread interactions to monitors would greatly improve the chance that they wouldn't interfere with each other in unanticipated ways.

A number of variants on the idea of monitors have been proposed and implemented in various programming languages such as Concurrent Pascal, Mesa, Concurrent Euclid, Turing and more recently Java. The idea of single-threaded access to a monitor is straightforward and the same in all these variants; where they differ is in how threads wait for the state of the monitor to change, and how they communicate to each other that the state has changed. Of all the these approaches, I've always found Hoare's version the easiest to use. In Hoare's version, occupancy of the monitor is transferred directly from a signaling to a signaled thread: the state of the monitor object cannot change between the signaling thread leaving and the signaled thread arriving.

A Java-based implementation of Hoare-style monitors

For the rest of this article I'll focus on a Java package I've developed that implements Hoare-style monitors. In addition to being a straightforward Java-based implementation of Hoare's original concept, the monitor package has one novel feature: it allows all assertions used in designing a monitor to be expressed as part of the code and checked at runtime.

To get started, Table 1 summarizes the classes in the monitor package. See the Resources section for the source code for the monitor package.

Table 1. Summary of interfaces

public abstract class AbstractMonitorAbstract base class for monitor
       protected AbstractMonitor()Constructor
       protected boolean invariant()Hook method for invariant
       protected void enter()Obtain occupancy
       protected void leave()Relinquish occupancy
       protected Condition makeCondition( Assertion p )Make a condition object
       protected Condition makeCondition()Make a condition with an always true assertion
 
public class MonitorMonitor objects for delegation.
       public Monitor(Assertion invariant)Construct a monitor with a given invariant
        public void enter()Obtain occupancy
       public void leave()Relinquish occupancy
       public Condition makeCondition( Assertion p )Make a condition object
       public Condition makeCondition()Make a condition with an always true assertion
 
public class ConditionCondition objects
       public void await()Wait for an assertion Pc to become true
       public void conditionalAwait()If Pc is not true, wait until it is
       public void signal()Signal that Pc is true
        public void conditionalSignal()If Pc is true, signal so
       public void signalAndLeave()Signal that Pc is true and leave the monitor
       public void conditionalSignalAndLeave()If Pc is true, signal so and leave the monitor
        public int count()The number of threads waiting
       public boolean isEmpty()Is the number of threads waiting 0?
 
public abstract class AssertionExecutable assertion objects
       public abstract boolean isTrue()Hook method
1 2 3 4 Page 1
Page 1 of 4