Subtle difference in wait / notify

S

stixwix

Hi,
Can anyone explain this behaviour? It is basically the minimum amount
of code to set up a thread that waits until it is notified by the main
thread.
In this code the notify does not work because of the way it uses an
instance of the Outer class to specify the Runnable passed to the
Thread constructor.
However, if the first two lines of the test method are replaced by:
Thread t = new Thread(new Worker());
it works as expected.

public class Outer {
private Object lock = new Object();
public class Worker implements Runnable {
public void run(){
synchronized(lock){
try {
lock.wait();
}
catch (InterruptedException e) {}
}
}
}
public void test(){
Outer out = new Outer();
Thread t = new Thread(out.new Worker());
t.start();
// allow enough time for the thread to enter wait
Thread.sleep(100);
synchronized(lock) {
lock.notifyAll();
}
}
}
 
T

Thomas Hawtin

stixwix said:
Can anyone explain this behaviour? It is basically the minimum amount
of code to set up a thread that waits until it is notified by the main
thread.

Where did you get that code from?
In this code the notify does not work because of the way it uses an
instance of the Outer class to specify the Runnable passed to the
Thread constructor.
However, if the first two lines of the test method are replaced by:
Thread t = new Thread(new Worker());
it works as expected.

With the out.new Worker() version you are using a different Outer and
hence lock object for the wait than for the notify. The new Worker()
version, with implicit this., uses the same object for both wait and notify.
public class Outer {
private Object lock = new Object();
public class Worker implements Runnable {
public void run(){
synchronized(lock){
try {
lock.wait();
}
catch (InterruptedException e) {}
}
}
}
public void test(){
Outer out = new Outer();
Thread t = new Thread(out.new Worker());
t.start();
// allow enough time for the thread to enter wait
Thread.sleep(100);
synchronized(lock) {
lock.notifyAll();
}
}
}

Tom Hawtin
 
T

Thomas Fritsch

stixwix said:
Hi,
Can anyone explain this behaviour? It is basically the minimum amount
of code to set up a thread that waits until it is notified by the main
thread.
In this code the notify does not work because of the way it uses an
instance of the Outer class to specify the Runnable passed to the
Thread constructor.
However, if the first two lines of the test method are replaced by:
Thread t = new Thread(new Worker());
it works as expected.

public class Outer {
private Object lock = new Object();
public class Worker implements Runnable {
public void run(){
synchronized(lock){
try {
lock.wait();
}
catch (InterruptedException e) {}
}
}
}
public void test(){
Outer out = new Outer();
Thread t = new Thread(out.new Worker());
t.start();
// allow enough time for the thread to enter wait
Thread.sleep(100);
synchronized(lock) {
lock.notifyAll();
}
You synchronize and notify on the wrong lock object (not the same as
used in your wait). When you change the above 3 line to
synchronized(out.lock) {
out.lock.notifyAll();
}
it will work again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top