0

I was reading multi threading in Java from the book Java The Complete Reference by Herbert Schildt. I came across following code [Pg. 252, 7th ed.] that explained the usage of wait() and notify() to suspend and resume threads in modern Java. My question is regarding the significance of the keyword synchronization at two places in following code (in run() method of class NewThread):

// Suspending and resuming a thread the modern way.
class NewThread implements Runnable {
    String name;
    Thread t;
    boolean suspendFlag;
    NewThread(String threadname) {
        name = threadname;
        t = new Thread(this, name);
        suspendFlag = false;
        t.start();
    }
// This is the entry point for thread.
    public void run() {
        try {
            for (int i = 15; i > 0; i--) {
                System.out.println(name + ": " + i);
                Thread.sleep(200);
                synchronized (this) { //First doubt here
                    while (suspendFlag) {
                        wait();
                    }
                }
            }
        } catch (InterruptedException e) {
            System.out.println(name + " interrupted.");
        }
        System.out.println(name + " exiting.");
    }
    void mysuspend() {
        suspendFlag = true;
    }
    synchronized void myresume() { //Second doubt here
        suspendFlag = false;
        notify();
    }
}

class SuspendResume {
    public static void main(String args[]) {
        NewThread ob1 = new NewThread("One");
        NewThread ob2 = new NewThread("Two");
        try {
            Thread.sleep(1000);
            ob1.mysuspend();
            Thread.sleep(1000);
            ob1.myresume();
            ob2.mysuspend();
            Thread.sleep(1000);
            ob2.myresume();
        } catch (InterruptedException e) {
            System.out.println("Main thread Interrupted");
        }
        //some code
}

My doubt here: I know about the use of keyword synchronization i.e. allowing only one thread to enter a synchronized method on the same object but here we have two threads running on two different objects. So what is the significance of both synchronization keywords used in above code.

I tried running the above code by removing the synchronized keyword at each place differently and simultaneously. I am getting the same error: java.lang.IllegalMonitorStateException: current thread is not owner different number of times and at different line numbers depending upon if I remove both or only one (and which one) synchronization keyword. I looked for the above error and found an explanation for it here but still couldn't connect the answer to my doubt.

ATK
  • 358
  • 3
  • 17

1 Answers1

0

The problem that synchronized solves is, it allows the two threads to have a consistent view of the shared suspendFlag variable.

In some real program, a thread might set other shared variables before setting susependFlag=false. If synchronized was not used, then the waiting thread could wake up, and see suspendFlag==false, but not see the other variables set. Or worse, it could see some of them set, but not others.

Without synchronization, Java does not guarantee that different threads will see variables updated in the same order.

I am getting the same error: java.lang.IllegalMonitorStateException: current thread is not owner.

The Java library is trying to help you by forcing you to use synchronized before it will allow you to use wait() and notify(). The rule is simple: You can only call o.wait() or o.notify() or o.notifyAll() from code that is inside a synchronized(o) block. If you break that rule, then the library throws the exception.

When your code calls o.wait() the wait() call temporarily unlocks the monitor lock so that the other thread will be able to synchronize on o and call o.notify(). The o.wait() call is guaranteed to re-lock o before it returns.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
  • Need one clarification. I think I confused the threads that are synchronized here (I thought synchronization is between the threads "One" and "Two"). The synchronization happens between the `main` thread and the new thread created in class `NewThread`? – ATK Aug 06 '20 at 08:35
  • 1
    @Lambda "Synchronization isn't really between threads at all: It's between each thread and the program's variables. Most of what you need to know about `synchronized` can be summed up in two sentences; (a) No two threads can ever by `synchronized` on the same object at the same time, and (b) Whatever changes one thread makes to shared variables before it leaves a `synchronized(o)` block, they're all guaranteed to be visible to any other thread after the other thread has entered a `synchronized(o)` block for the same object, `o`. – Solomon Slow Aug 06 '20 at 11:21