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:
- Possibly more overhead (Please justify)
- Vulnerable to spurious wakeups
- Doesn't always protect mutable state of the object sufficiently (because of the different locks in use).
- Doesn't check for conditions already being true (which doesn't apply to all conditions, of course).
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