Thread is going in infinite wait state

63 views Asked by At

Given an integer N, the task is to write a Java program to print the first N natural numbers in increasing order using two threads. However, the output is only showing the number 1 as the thread is going into an infinite loop and this is something the user could not debug.

public class OddEven {
    static int totalNos;
    static int counter = 1;
    static Runnable odd = new Runnable() {
        @Override
        public void run() {
            synchronized (this) {
                while(counter < totalNos) { 
                    while (counter%2==0) {
                        try {
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print(counter + " ");
                    counter++;
                    notify();
                }
            }
        }
    };
    
    static Runnable even = new Runnable() {
        @Override
        public void run() {
            synchronized (this) {
                while(counter < totalNos) {
                    while (counter%2==1) {
                        try {
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print(counter + " ");
                    counter++;
                    notify();
                }
            }
        }
    };
    
    public static void main(String[] args) {
        System.out.println("Enter the total no's");
        Scanner scObj = new Scanner(System.in);
        totalNos = scObj.nextInt();
        scObj.close();
        Thread oddT1 = new Thread(odd);
        Thread evenT1 = new Thread(even);
        oddT1.start();
        evenT1.start();  
      
    }
}
1

There are 1 answers

8
Solomon Slow On

You have no synchronization between the two objects. Each of your two objects, even and odd synchronizes on its own self, waits on its own self, and notifies its own self. Or, more accurately, it would notify its own self if it ever got to that point, but it doesn't get there because the other thread never notifies it.

You need to have both threads use the same object for synchronization. E.g.;

public class OddEven {
    static final Object lock = new Object();
    static int totalNos;
    static int counter = 1;
    static Runnable odd = new Runnable() {
        @Override
        public void run() {
            synchronized (lock) {
                ...
                lock.wait();
                ...
                lock.notify();
            }
        }
    }
    .
    .
    .
}