Details methods of suspending restoring and terminating threads in Java programming

  • 2020-04-01 04:12:23
  • OfStack

Sometimes, thread hang-ups are useful. For example, a separate thread can be used to display the time of day. If the user does not want to use a clock, the thread is suspended. In any case, it is easy to suspend a thread, and it is easy to restart the thread once it is suspended.

The hang, terminate, and resume threading mechanisms are different in Java 2 and earlier versions. Although you write code in the Java 2 way, you still need to understand how this was done in the early Java environment. For example, you may need to update or maintain old code. You also need to understand why Java 2 has changed this way. For these reasons, the following describes the original method of performing thread control, followed by the Java 2 method.
Suspension, recovery, and termination of threads in Java 1.1 or earlier

Prior to Java2, programs used suspend() and resume() defined for threads to suspend and restart threads. They take the form of:


  final void suspend( )
  final void resume( )


The following program describes these methods:


// Using suspend() and resume().
class NewThread implements Runnable {
  String name; // name of thread
  Thread t;
  NewThread(String threadname) {
    name = threadname;
    t = new Thread(this, name);
    System.out.println("New thread: " + t);
    t.start(); // Start the thread
  }
  // 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);
      }
    } catch (InterruptedException e) {
      System.out.println(name + " interrupted.");
    }
    System.out.println(name + " exiting.");
  }
}
class SuspendResume {
  public static void main(String args[]) {
    NewThread ob1 = new NewThread("One");
    NewThread ob2 = new NewThread("Two");
    try {
      Thread.sleep(1000);
      ob1.t.suspend();
      System.out.println("Suspending thread One");
      Thread.sleep(1000);
      ob1.t.resume();
      System.out.println("Resuming thread One");
      ob2.t.suspend();
      System.out.println("Suspending thread Two");
      Thread.sleep(1000);
      ob2.t.resume();
      System.out.println("Resuming thread Two");
    } catch (InterruptedException e) {
      System.out.println("Main thread Interrupted");
    }
    // wait for threads to finish
    try {
      System.out.println("Waiting for threads to finish.");
      ob1.t.join();
      ob2.t.join();
    } catch (InterruptedException e) {
      System.out.println("Main thread Interrupted");
    }
    System.out.println("Main thread exiting.");
  }
}

The partial output of the program is as follows:


New thread: Thread[One,5,main]
One: 15
New thread: Thread[Two,5,main]
Two: 15
One: 14
Two: 14
One: 13
Two: 13
One: 12
Two: 12
One: 11
Two: 11
Suspending thread One
Two: 10
Two: 9
Two: 8
Two: 7
Two: 6
Resuming thread One
Suspending thread Two
One: 10
One: 9
One: 8
One: 7
One: 6
Resuming thread Two
Waiting for threads to finish.
Two: 5
One: 5
Two: 4
One: 4
Two: 3
One: 3
Two: 2
One: 2
Two: 1
One: 1
Two exiting.
One exiting.
Main thread exiting.

The Thread class also defines stop() to terminate the Thread. It takes the form of:


  void stop( )


Once a thread is terminated, it cannot be resumed by resume().
Suspend, restore, and terminate threads in Java

The suspend(), resume(), and stop() methods of Thread definition seem to be perfect and convenient ways to manage threads, and they are not available for new Java versions of programs. Here's why. The suspend() method of the Thread class is disapproved in Java2 because suspend() can sometimes cause serious system failures. Suppose a thread is locked on a key data structure, and if the thread hangs there, the locked thread does not relinquish control of the resource. Other threads waiting on these resources may be deadlocked.

The Resume() method is also disapproved. It does not cause problems, but cannot be used independently from the suspend() method. The stop() method of the Thread class is also opposed in Java 2. This is because this approach can lead to serious system failures. Imagine a thread that is writing a precise and important data structure and completing only a fraction of it. If the thread terminates at this point, the data structure may remain in a collapsed state.

Since you can't use the suspend(), resume(), and stop() methods to control threads in Java 2, you might think there's no way to stop, restore, or end threads. It's not. Instead, the thread must be designed so that the run() method checks periodically to determine whether the thread should be suspended, resumed, or terminated from its own execution. Typically, this is done by creating a flag variable that indicates the status of the thread. As long as the flag is set to "running," the run() method must continue to let the thread execute. If the flag is "suspend", the thread must be suspended. If set to "stop", the thread must terminate.

Of course, there are many ways to write such code, but the central theme should be the same for all programs.

The following example illustrates how the wait() and notify() methods inherited from Object control thread execution. This example is very similar to the previous program. However, none of the disapproved methods were used. Let's think about the execution of the program.

The NewTread class contains a Boolean instance variable suspendFlag to control thread execution. It is initialized to false by the constructor. The Run() method contains a block that monitors the synchronization declaration of suspendFlag. If the variable is true, the wait() method is called to suspend the thread. The Mysuspend() method sets the suspendFlag to true. The Myresume() method sets the suspendFlag to false and calls the notify() method to invoke the thread. Finally, the main() method is modified to call the mysuspend() and myresume() methods.


// Suspending and resuming a thread for Java2
class NewThread implements Runnable {
  String name; // name of thread
  Thread t;
  boolean suspendFlag;
  NewThread(String threadname) {
    name = threadname;
    t = new Thread(this, name);
    System.out.println("New thread: " + t);
    suspendFlag = false;
    t.start(); // Start the thread
  }
  // 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) {
          while(suspendFlag) {
            wait();
          }
        }
      }
    } catch (InterruptedException e) {
      System.out.println(name + " interrupted.");
    }
    System.out.println(name + " exiting.");
  }
  void mysuspend() {
    suspendFlag = true;
  }
  synchronized void myresume() {
    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();
     System.out.println("Suspending thread One");
     Thread.sleep(1000);
     ob1.myresume();
     System.out.println("Resuming thread One");
     ob2.mysuspend();
     System.out.println("Suspending thread Two");
     Thread.sleep(1000);
     ob2.myresume();
     System.out.println("Resuming thread Two");
    } catch (InterruptedException e) {
     System.out.println("Main thread Interrupted");
    }
    // wait for threads to finish
    try {
     System.out.println("Waiting for threads to finish.");
     ob1.t.join();
     ob2.t.join();
    } catch (InterruptedException e) {
      System.out.println("Main thread Interrupted");
    }
    System.out.println("Main thread exiting.");
  }
}

The output of this program is the same as the previous program. Later in this book, you'll see more examples of using the Java 2 mechanism to control threads. Although this mechanism is not as "clean" as the old method, it is, however, a way to ensure that no errors occur at runtime. It is the approach that all new code must take.


Related articles: