0

I have tried some approaches like making a single class with differentiating properties but after 1 round it collapses. I understand the order but can't understand the reason.


public class Threading {

    public static void main(String[] args) {
        Notify runnable2=new Notify(null, 2);
        Notify runnable1=new Notify(runnable2, 1);
        Notify runnable3=new Notify(runnable1, 0);
        Thread t1=new Thread(runnable1,"T1");
        Thread t2=new Thread(runnable2,"T2");
        Thread t3=new Thread(runnable3,"T3");
        runnable2.setNotify(runnable3);
        t1.start();
        t2.start();
        t3.start();
    }
}
class Notify extends Thread {
    Notify notify;
    int remainder;
    static int number=100;
    static final Object lock=new Object();
    Notify(Notify notify, int remainder)
    {
        this.notify = notify;
        this.remainder = remainder;
    }
    void setNotify(Notify notify){
        this.notify = notify;
    }
    public void run() {
        while (number > 0) {
            synchronized (lock) {
                while (number % 3 != remainder) {
                    try {
                        if(notify!=null) notify.wait();
                        lock.notify();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + " " + number);
                number--;
                lock.notifyAll();
            }
        }
    }
}

but it results in

Exception in thread "T1" Exception in thread "T3" Exception in thread "T2" java.lang.IllegalMonitorStateException
  • 1
    You are calling `wait()` on `notify`; you should call it on `lock` instead: `lock.wait();` instead of `notify.wait();`. You can only call `wait` on an object in a `synchronized` block that blocks on that object. You synchronize on `lock`, not on `notify`. – Jesper May 11 '22 at 08:44
  • You can only call `wait()` on an object if you hold its monitor (have `synchronized` on the object). You synchronize on `lock`, not on `notify`. To be clear, fixing the cause of this exception by slapping a `syncronized` on `notify` will still result in broken code, as your idea wait on `notify` is fundamentally broken. – Mark Rotteveel May 11 '22 at 08:44
  • @JoachimSauer `lock` is a static field, so it is shared by all, though using the runnables as something to notify on seems fishy in a similar vein. – Mark Rotteveel May 11 '22 at 08:45
  • @MarkRotteveel: right, I missed that. – Joachim Sauer May 11 '22 at 08:48

0 Answers0