Reputation: 29
Thread t1 is going into Deadlock after wait()
is hit. even though
there is notify()
in t2. Code is getting into deadlock.
Not getting Print statement - "After wait is released ::::"
I can see both threads competing to acquire the monitor in counterAdd()
. Therefore, I assumed notify will work.
package com.java.thread.practice;
public class WaitAndNotify4 {
int counter = 0;
/*
CounterAdd() is to be accessed by both t1 and t2.
If not synchronized not giving consistent output.
*/
synchronized int counterAdd(){
return counter++;
}
public static void main(String[] args) throws InterruptedException{
// Creating method to call the threads.
WaitAndNotify4 andNotify4 = new WaitAndNotify4();
andNotify4.testRaceCondition();
}
private void testRaceCondition() throws InterruptedException {
// Thread t1 created and launched.
Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
for(int i=0; i<5; i++){
synchronized(this){
if(i== 1){
System.out.println("Calling wait after count 1");
try {
// Assuming that this wait will be resumed by notify in t2.
wait();
System.out.println("After wait is released :::: ");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
counterAdd();
}
}
});
Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0; i<5; i++){
if(i==2){
synchronized(this){
System.out.println("Before releasing the counter :::::");
notify();
System.out.println("After releasing the counter :::::");
}
}
counterAdd();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(" Sum value is found as ::::: "+counter);
}
}
Upvotes: 1
Views: 287
Reputation: 9569
You are synchronizing on different objects. In first case on object t1
, in second on t2
, in method counterAdd
on andNotify4
. In order to place lock on andNotify4
all the time you need to do something like that.
public class Main {
private int counter = 0;
synchronized int counterAdd() {
return counter++;
}
public static void main(String[] args) throws InterruptedException {
Main andNotify4 = new Main();
andNotify4.testRaceCondition();
}
private void testRaceCondition() throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
synchronized (Main.this) {
if (i == 1) {
System.out.println("Calling wait after count 1");
try {
Main.this.wait();
System.out.println("After wait is released :::: ");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
counterAdd();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
if (i == 2) {
synchronized (Main.this) {
System.out.println("Before releasing the counter :::::");
Main.this.notify();
System.out.println("After releasing the counter :::::");
}
}
counterAdd();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(" Sum value is found as ::::: " + counter);
}
}
Upvotes: 1