SynchronizeOnEvents

Last edit August 15, 2014
Change...
 public class NormalJavaWaitIdiom{
   Object monitor;
   boolean someState = false;
   boolean someOtherState = false;

public void someMethod(){ synchronized(monitor){ while(!someState) monitor.wait(); } }

public void someOtherMethod(){ synchronized(monitor){ while(!someOtherState) monitor.wait(); } }

public void notifySomeStateChange(){ synchronized(monitor){ someState = true; monitor.notifyAll(); } } }
into
 public class ProposedWaitIdiom
   Object notableEvent;
   Object otherNotableEvent;

public void someMethod(){ synchronized(notableEvent){ notableEvent.wait(); } }

public void someOtherMethod(){ synchronized(otherNotableEvent){ otherNotableEvent.wait(); } }

public void notifySomeStateChange(){ synchronized(notableEvent){ notableEvent.notify(); } } }

Pros:
  • Clearly indicates intent of synchronizing object; in some cases, a state variable can be totally replaced by this.
  • common 'notify()' instead of 'notifyAll()' becomes much more obvious: instead of having the situation of 'Do we only wake up one thread which could could be affected', we get 'Do we want only one thread acting on this event?'.

Cons:
JavaLanguage concurrency sure is "subtle". These two examples have very different semantics:
  • In the first, all subscribers to the event will return when it "fires". In the second, only one will. The "Pros" section suggests this is desirable, but I'm not sure if that's a note by the author (who'd know the intent of the original code), or another WikiReader guessing what it was supposed to do!
  • In the first, once the event has fired once, the state will remain "true" and future callers will return without waiting. In the second, future callers will block until the next event.
Maybe what's needed is a third version, which is like one of these but with a clear statement of what it's supposed to do, and code that matches it :-). -- LukeGorrie


CategoryJava CategoryConcurrency CategoryEvents