javamultithreadingsynchronizedsynchronized-block

suspending, resuming and stopping threads in java


I'm learning Thread in java.

The following example shows how to suspend, resume and stop threads:

class MyNewThread implements Runnable {
Thread thrd;

boolean suspended;
boolean stopped;

MyNewThread(String name) {
    thrd = new Thread(this, name);
    suspended = false;
    stopped = false;
    thrd.start();
}

public void run() {
    System.out.println(thrd.getName() + " starting.");
    try {
        for(int i = 0; i<1000; i++) {
            System.out.print(i + " ");
            if(i%10 == 0) {
                System.out.println();
                Thread.sleep(250);
            }

            synchronized(this) {
                while(suspended) {
                    wait();
                }
                if(stopped) break;
            }
        }
    } catch(InterruptedException ex) {
        System.out.println(thrd.getName() + " interrupted.");
    }
    System.out.println(thrd.getName() + " exiting.");
}

synchronized void mystop() {
    stopped = true;
    suspended = false;
    notify();
}

synchronized void mysuspend() {
    suspended = true;
}

synchronized void myresume() {
    suspended = false;
    notify();
}
}

public class Suspend {
public static void main(String[] args) {
    MyNewThread ob1 = new MyNewThread("My Thread");     
    try {
        Thread.sleep(1000);

        ob1.mysuspend();
        System.out.println("Suspending Thread.");
        Thread.sleep(1000);

        ob1.myresume();
        System.out.println("Resuming Thread.");
        Thread.sleep(1000);

        ob1.mysuspend();
        System.out.println("Suspending Thread.");
        Thread.sleep(1000);

        ob1.myresume();
        System.out.println("Resuming Thread.");
        Thread.sleep(1000);

        ob1.mysuspend();
        System.out.println("Stopping Thread.");
        ob1.mystop();
    } catch(InterruptedException ex) {
        System.out.println("Main Thread interrupted.");
    }

    try {
        ob1.thrd.join();
    } catch(InterruptedException ex) {
        System.out.println("Main Thread interrupted.");
    }
    System.out.println("Main Thread exiting.");
}
}

But this block:

synchronized(this) {
    while(suspended) {
        wait();
    }
    if(stopped) break;
}

Why this block must be specified synchronized?

I know "synchronized" uses to control Threads's access to shared resource and how to use this key word, but in the example, there're only 2 threads: Main thread and ob1 thread. And Main thread does not enter that synchronized block or any synchronized method in MyThread class. I just cant figure out the reason.

I tried to remove the "synchronized" key word precedes the block. the program returned an error in thread "My Thread" while the main thread still finished it's execution.


Solution

  • To answer your direct question: you need to synchronize on this because you are calling wait() on this.

    And in order for wait() to be called, the calling thread must own the monitor of the object wait() is called on.

    So: you need that synchronized block (or method) to prevent an IllegalMonitorStateException for the following call to wait()!