1

HI wrote a sample program for testing the behavior of wait in java.

My implementation of Runnable:

class ThreadWait implements Runnable {
    Object lock = new Object();
    ThreadWait(Object lock){
        this.lock = lock;
    }
    @Override
    public void run() {
        try {
            synchronized (lock){
                System.out.println("Started : "+Thread.currentThread().getName());
                wait();
                System.out.println("Completed : "+Thread.currentThread().getName());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Used within my main like:

Object lock = new Object();
ThreadWait t1 = new ThreadWait(lock);
ThreadWait t2 = new ThreadWait(lock);
Thread a= new Thread(t1);
a.setName("A");
Thread b= new Thread(t2);
b.setName("B");
a.start();
b.start();

When running this program I am getting this exception:

Exception in thread "A" Exception in thread "B" java.lang.IllegalMonitorStateException
Started : A
    at java.lang.Object.wait(Native Method)
Started : B
    at java.lang.Object.wait(Object.java:502)
    at ThreadWait.run(SynchronizedExample.java:34)
    at java.lang.Thread.run(Thread.java:745)
java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)
    at ThreadWait.run(SynchronizedExample.java:34)
    at java.lang.Thread.run(Thread.java:745)
GhostCat
  • 137,827
  • 25
  • 176
  • 248
robin
  • 1,893
  • 1
  • 18
  • 38

1 Answers1

6

Your problem is that you synchronized on lock, but you are waiting on this (specifically: the instance of Runnable that contains the wait call).

You can only call wait on objects that you own the monitor on. Your code owns lock, but not this!

So you should wait on the lock object. But please note: then your code will deadlock!

That leads to the advice: you should study the "theory" a bit more. You see, one can use wait/notify in order to "synchronize" different threads that are supposed to work on the same data; but that is not something you learn (efficiently) by trial and error; as there are simply too many subtle details that influence the outcome of trial and error experiments. You might start reading here or there.

One final word: it is also important to understand that, yes, wait/notify are important concepts; but you rarely use them in "the real world". These are very low-level mechanisms, and Java has added more powerful abstractions on top of them.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248