0

I am trying to execute 2 threads in interleaved manner. One is printing odd numbers and other is printing even numbers to the console (<=100). I want the output to be : 1 2 3 4 5 6 7 8 9 10 .... and so on. i.e they should execute one after another in order.

Here is the code for this:

class Monitor{
    boolean flag = false;
}

class OddNumberPrinter implements Runnable{
    Monitor monitor;
    OddNumberPrinter(Monitor monitor){
        this.monitor = monitor;
    }

    @Override
    public void run() {
        for (int i = 1; i<100; i+=2){

            synchronized (monitor){
                while(monitor.flag == true){
                    try {
                        wait();
                    } catch (Exception e) {}
                }
                System.out.print(i+"  ");
                monitor.flag = true;
                notify();
            }
        }
    }
}
class EvenNumberPrinter implements Runnable{
    Monitor monitor;
    EvenNumberPrinter(Monitor monitor){
        this.monitor = monitor;
    }

    @Override
    public void run() {
        for (int i = 2; i<101; i+=2){
            synchronized (monitor){
                while (monitor.flag == false){
                    try {
                        wait();
                    } catch (Exception e) {}
                }
                System.out.print(i + "  ");
                monitor.flag = false;
                notify();
            }
        }
    }
}
public class InterleavingThreads {

    public static void main(String[] args) throws InterruptedException {
        Monitor monitor = new Monitor();
        Thread t1 = new Thread(new OddNumberPrinter(monitor));
        Thread t2 = new Thread(new EvenNumberPrinter(monitor));

        t1.start();
       t2.start();
    }
}

When I standalone use wait() and notify(), it throws exception, but using monitor.wait() and monitor.notify() gives the correct output. Please explain the difference in these two.

  • `wait` is `this.wait` and `notify` is `this.notify`. So you are locking on whatever `this` is. What exception are you getting ? – ygor Dec 03 '18 at 10:06
  • The difference is that you have synchronized on `monitor`, but you have not synchronized on `this`. https://stackoverflow.com/questions/2779484/why-must-wait-always-be-in-synchronized-block?rq=1 – Thilo Dec 03 '18 at 10:06
  • 2
    There is no 'standalone `wait()` or `notify()` method. They are all methods on objects. When you omit the object designator, `this` is assumed. You are synchronizing on `monitor`, not `this`, so `this.wait()/notify()` throw exceptions. This is all documented. – user207421 Dec 03 '18 at 10:06
  • @ygor IllegalMonitorStateException, – Abhijeet Chatarjee Dec 03 '18 at 10:28
  • So we make thread wait on "monitor" object only? Also, I could not simply using 'Boolean' class object instead of creating 'Monitor' class to use as a monitor, booleanObject.wait() and booleanObject.notify() was not working, they were also causing the same exceptions. Any help will be appreciated. @user207421 – Abhijeet Chatarjee Dec 03 '18 at 10:35
  • And the exceptions are...? – Jason Armstrong Dec 03 '18 at 11:11
  • @JasonArmstrong Only 'IllegalMonitorStateException' – Abhijeet Chatarjee Dec 03 '18 at 11:30

0 Answers0