1

I've been trying to make a simple Java thread application, where one thread waits, and another wakes it up after 3 seconds. However, I can't seem to make it work and I just can't figure out why.

public class Deadlock extends Thread {

Object lock = new Object();

public static void main(String[] args) {

    //WAITER THREAD
    Deadlock waiter = new Deadlock() {

        @Override
        public void run() {
            System.out.println("Waiter started");
            synchronized(lock) {
                try{
                    System.out.println("Waiter will wait for notify...");
                    lock.wait();
                    System.out.println("Woke up!");
                } catch(InterruptedException e) { 
                    e.printStackTrace();
                }
            }
        }//run()

    };

    //WAKER THREAD
    Deadlock waker = new Deadlock() {

        @Override
        public void run() {
            System.out.println("Waker started");
            synchronized(lock) {
                System.out.println("Waker sleeping for 3 seconds.");
                try{
                    Thread.sleep(3000);
                }catch(InterruptedException e) {}
                System.out.println("Waker notifying...");
                lock.notifyAll();
            }
        }//run

    };

    waiter.start();
    waker.start();
}

}

The output I get is:

Waiter started
Waiter will wait for notify...
Waker started
Waker sleeping for 3 seconds.
Waker notifying...

...and keeps running forever. I expected the waiter thread to wake up and the program to terminate.

Thanks

plafer
  • 185
  • 12

1 Answers1

4

Your main problem is that the 'lock' is a class instance property so the two Deadlock instances do not share the same 'lock'. Hence, calling notifyAll() in the waker has no effect on the waiter because it's waiting on a different object. The simplest solution is to make 'lock' static:

static Object lock = new Object();

... I'd also make it private and final for good measure.

The second issue is that by starting the two threads together you don't really guarantee that the waiter will run first - I'd add a short delay before starting the waker.

BarrySW19
  • 3,759
  • 12
  • 26
  • By the way, the java.util.concurrent package provides better ways to control concurrency and is worth a look. – BarrySW19 Mar 16 '15 at 16:53