Why do wait and notify function not working properly on same class lock?
Please see check below code for wait and notify functionality and its output.
Output:
Thread-1
Thread-2
Thread-2 after notify
Expected Result:
Thread-1
Thread-2
Thread-2 after notify
Thread-1 after wait
Code:
public class WaitAndNotify1 {
public static void main(String[] args) {
Thread t1=new Thread(new Runnable(){
@Override
public void run(){
System.out.println("Thread-1");
try {
synchronized (this) {
wait();
System.out.println("Thread-1 after wait");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2=new Thread(new Runnable(){
@Override
public void run(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread-2");
synchronized (this) {
notify();
System.out.println("Thread-2 after notify");
}
}
});
t1.start();
t2.start();
}
}
You're using this
from an anonymous inner class - so it refers to the instance of that anonymous inner class. There are two different instances (of different anonymous inner classes) so you're calling wait()
on a different object from the one you're calling notify()
on.
You don't actually have an instance of WaitAndNotify1
to synchronize on at the moment. You could move the code to an instance method, then use WaitAndNotify1.this
to refer to the instance - at which point you'll get your expected output:
public class WaitAndNotify1 {
public static void main(String[] args) {
new WaitAndNotify1().test();
}
public void test() {
Thread t1=new Thread(new Runnable(){
@Override
public void run(){
System.out.println("Thread-1");
try {
synchronized (WaitAndNotify1.this) {
WaitAndNotify1.this.wait();
System.out.println("Thread-1 after wait");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2=new Thread(new Runnable(){
@Override
public void run(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread-2");
synchronized (WaitAndNotify1.this) {
WaitAndNotify1.this.notify();
System.out.println("Thread-2 after notify");
}
}
});
t1.start();
t2.start();
}
}
See more on this question at Stackoverflow