<< Enscript, Cygwin, Lpr, ... | Home | Generating HTML From Code With Enscript >>

Thread Synchronization Puzzle

Take a look at the code below. Should Main finish immediately? Under Sun J2SE SDK 1.4.2_04 on Fedora Core 1 Linux it does. Under gij 3.3.2 (the JVM in GCC 3.3.2) it doesn't. Intuitively, the worker thread waits on lock, which is never notified, so worker should be waiting indefinitely. Right?

public class Main {
    public static void main(String[] args) {
        final Thread lock = new Thread();
        Thread worker = new Thread() {
            public void run() {
                synchronized (lock) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
        };
        worker.start();
        lock.start();
    }
}


Re: Thread Synchronization Puzzle

You should always be very careful which object you use for wait/notify synchronization.

You never know what code might be calling .notify() on a Thread; though I can't think of what would be doing so in this instance.

This is why I always use java.lang.Object for my lock objects.

Re: Thread Synchronization Puzzle

I think the issue in this case is does the worker thread start (and get as far as the wait) before the lock thread starts. It's a race. Perhaps one implementation gives a newly started thread an immediate slice of cycles, perhaps not.

What is locked may be irrelevant. I prefer to lock on private final Objects. With the lock mechanism being public in all classes, it can rather get overlooked.

If you don't want race conditions, you can always use run() instead of start(). :)

Re: Thread Synchronization Puzzle

It feels as if a Thread calls notifyAll() on itself when it returns from its run() method. But I couldn't find any documentation that support my suspicion.

Re: Thread Synchronization Puzzle

Right, it should wait indefinitely. Is it finishing immediately because the thread is interrupted, because the thread is notified, or because the JVM is treating it as a daemon thread? Put in some debug statements, and let's find out.

Re: Thread Synchronization Puzzle

Oh, yeah, that last comment was me. ;)

Re: Thread Synchronization Puzzle

1.5 "clarifies" the documentation on Object.wait. It can wake up spontaneously. Probably not central to this issue, but something to watch anyway (java.awt.EventQueue.invokeAndWait gets it wrong).

Re: Thread Synchronization Puzzle

Thanks Tom, that's the pointer I needed. I assume the new javadoc is a bug fix for the 1.4 javadoc.

Here's what the new Javadoc says: "A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup."

Spurious wakeup! That's just lovely. Someone ought to write a song about it.

To answer Bob's question, the wake up will happens only if wait() is called before lock.run() returns, and it happens when lock.run() returns.


Add a comment Send a TrackBack