[concurrency-interest] Roach motels

Jeremy Manson jmanson at cs.purdue.edu
Wed Nov 16 16:36:57 EST 2005


Steve Kautz wrote:

> boolean foo()
> {
> synchronized(this)
> {
> if (inProgress) return false;
> inProgress = true;
> }
> 
> // make this call without lock
> Result result = someOtherObject.bar();
> 
> synchronized(this)
> {
> updateState(result);
> inProgress = false;
> return true;
> }
> }
> 
> When is the compiler allowed to move the call to bar() into the upper sync
> block or to coalesce the two blocks?
> 
> I'm just wondering about several situations that have come up recently in
> which we need to guarantee that the call to bar() is made without holding
> the sync lock. This is generally to avoid a possible deadlock, but it may be
> for other liveness-related reasons (call to bar() may block).

The system is allowed to introduce fairness issues, but can't introduce 
deadlock.  This is because fairness is considered a quality-of-service 
guarantee, but deadlock is considered a correctness issue.

For example, if you have:

while (true) {
   synchronized (this) {
     // stuff
   }
}

The system could change it to this:

synchronized (this) {
   while (true) {
     // stuff
   }
}

Any other thread that actually wants to acquire the lock on this would 
wait forever, which is legal under the Java spec.  This falls under the 
same category of badness as giving all of the runtime to a single 
thread, and never allowing another thread to run.  It's legal, but a 
well-designed system would probably not do it.

OTOH, a system cannot, in general, take this:

   synchronized (this) {
     // stuff
   }
   synchronized (that) {
     // more stuff
   }
   synchronized (this) {
     // even more stuff
   }

and change it to this:

synchronized (this) {
   // stuff

   synchronized (that) {
     // more stuff
   }

   // even more stuff
}

because this can introduce deadlock, which may introduce errors in your 
program.

Interesting aside: There are caveats to this, but those caveats should 
never be seen to affect the correctness of your program.  An example of 
such a caveat would be if the system can determine that the lock on 
"that" is never acquired by any other thread.  In this case, it can do 
the lock coalescing, because doing so won't introduce deadlock.

					Jeremy


More information about the Concurrency-interest mailing list