Sometimes thread hangs are useful. For example, a separate thread can be used to display the time of the day. If the user does not want to use the clock, the thread is suspended. In any case, suspending the thread is very simple, and once it is suspended, restarting the thread is also a simple matter.
The mechanisms for suspending, terminating and restoring threads differ in Java 2 and earlier versions. Although you use Java 2 to write code, you still need to understand how these operations were 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 such changes. For these reasons, the following describes the original method of executing thread control, followed by the Java 2 method.
Pause, recovery, and termination of threads in Java 1.1 or earlier
Before Java2 version, the program uses Thread-defined suspend() and resume() to pause and restart threads. They are in the form of:
final void suspend( ) final void resume( )
The following procedure describes these methods:
// Using suspend() and resume().class NewThread implements Runnable { String name; // name of thread Thread t; NewThread(String threadname) { name = thre adname; 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(); S ystem .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.o ut.println ("Main thread exiting."); }} Part of the program output is as follows:
New thread: Thread[One,5,main]One: 15New thread: Thread[Two,5,main]Two: 15One: 14Two: 14One: 13Two: 13One: 12Two: 11Two: 11Suspending thread OneTwo: 10Two : 9Two: 8Two: 7Two: 6Resuming thread OneSuspending thread TwoOne: 10One: 9One: 8One: 7One: 6Resuming thread TwoWaiting for threads to finish.Two: 5One: 5Two: 4One: 4Two: 3One: 3 Two: 2One: 2Two: 1One: 1Two exiting.One exiting.Main thread exiting.
The Thread class also defines stop() to terminate the thread. Its form is as follows:
void stop( )
Once the thread is terminated, it cannot be resumed by resume() to continue running.
Suspend, restore and terminate threads in Java
Thread-defined suspend(), resume() and stop() methods seem to be perfect and convenient ways to manage threads, and they cannot be used in new Java versions of programs. Here are the reasons. The suspend() method of the Thread class is not favored in Java2, because suspend() can sometimes cause serious system failures. Assuming that a thread for a critical data structure is locked, if the thread is suspended there, the locked threads do not give up control of the resource. Other threads waiting for these resources may be deadlocked.
The Resume() method is also not approved. It does not cause problems, but cannot be used independently without the suspend() method. The stop() method of the Thread class is also opposed in Java 2. This is because this method can cause serious system failures. Imagine a thread is writing a precise and important data structure and completing only one fraction of it. If the thread terminates at this moment, the data structure may remain in a crash state.
Because in Java 2, suspend(), resume() and stop() methods cannot be used to control threads, you may think that there is no way to stop, restore and end threads. Actually, it is not the case. Instead, the thread must be designed so that the run() method periodically checks to determine whether the thread should be suspended, resume or terminate its own execution. Representatively, this is done by establishing a flag variable indicating the state of the thread. As long as the flag is set to "running", the run() method must continue to be executed by the thread. If the flag is "suspend", the thread must be paused. If set to "stop", the thread must be terminated.
Of course, there are many ways to write such code, but the central topic should be the same for all programs.
The following examples illustrate how the wait() and notify() methods inherited from Object control the execution of threads. This example is very similar to the program mentioned earlier. However, none of the methods that are not approved are useful. Let us think about the execution of the program.
The NewTread class contains the instance variable suspendFlag used to control the execution of a thread. 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 suspendFlag to true. The Myresume() method sets suspendFlag to false and calls the notify() method to evoke the thread. Finally, the main() method is modified to call the mysuspend() and myresume() methods.
// Suspending and recovering a thread for Java2class NewThread implements Runnable { String name; // name of thread Thread t; boolean suspendFlag; NewThread(Str ing 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(in t 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 T wo"); } catch (InterruptedException e) { System.out.println("Main thread Interrupted"); } // wait for threads to finish try { System.out.println("Waiting for thre ads 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 that of the previous program. Later in this book, you will see more examples of using Java 2 mechanism to control threads. Although this mechanism is not as "clean" as the old method, however, it is the way to ensure that no errors occur at runtime. It is the method that all new code must take.