Java Multithreading - Life Cycle of Threads

Threads can be divided into 4 states:
New (new),
Runnable (runnable): For the convenience of analysis, they can also be divided into: Runnable and Running.
blocked,
Dead.

Like human beings, threads also experience four different states: start (waiting), running, suspending and stopping. These four states can be controlled by methods in the Thread class. The methods related to these four states in the Thread class are given below.

copy code
// start thread  
public void start( );  
public void run( );  
 
// suspend and wake up the thread  
public void resume( ); // deprecated  
public void suspend( ); // not recommended  
public static void sleep(long millis);  
public static void sleep(long millis, int nanos);  
public final native void wait() throws InterruptedException;
public final native void notify();
public final native void notifyAll();
 
// terminate the thread  
public void stop( ); // not recommended  
public void interrupt( );  
 
// get thread state  
public boolean isAlive( );  
public boolean isInterrupted( );  
public static boolean interrupted( );  
 
// join method  
public void join( ) throws InterruptedException;
copy code

1. Create and run a thread

After the thread is established, the code in the run method is not executed immediately, but is in a waiting state. When a thread is in a waiting state, various attributes of the thread can be set through the methods of the Thread class, such as thread priority (setPriority), thread name (setName) and thread type (setDaemon).

When the start method is called, the thread starts executing the code in the run method. The thread enters the running state. You can use the isAlive method of the Thread class to determine whether the thread is running. When the thread is running, isAlive returns true, when isAlive returns false, the thread may be in a waiting state, or it may be in a stopped state. The following code demonstrates the switching between the three states of thread creation, running and stopping, and outputs the corresponding isAlive return value.

copy code
package cn.thread;

/**
 * The life cycle
 *
 * @author Lin Jiqin
 * @version 1.0 2013-7-23 1:53:55 PM
 */
public class LifeCycle extends Thread {
    public void run() {
        int n = 0;
        while ((++n) < 1000)
            ;
    }

    public static void main(String[] args) throws Exception {
        LifeCycle thread = new LifeCycle();
        System.out.println("isAlive: " + thread.isAlive());
        thread.start();
        System.out.println("isAlive: " + thread.isAlive());
        thread.join(); // wait for the thread to end before continuing to execute
        System.out.println("thread has ended!");
        System.out.println("isAlive: " + thread.isAlive());
    }
}
copy code

It should be noted that the join method is used in the above code. The main function of this method is to ensure that the program continues to run after the thread's run method is completed . This method will be introduced in a later article.

The result of running the above code:

isAlive: false
isAlive: true
thread has ended!
isAlive: false

2. Suspend and wake up threads

Once the thread starts to execute the run method, it will not exit until the run method is completed. However, in the process of thread execution, there are two methods to temporarily stop the execution of the thread. The two methods are suspend and sleep. After suspending the thread with suspend, the thread can be awakened by the resume method. After using sleep to make the thread sleep, the thread can only be in the ready state after the set time (after the thread sleep ends, the thread may not be executed immediately, but only enters the ready state, waiting for the system to schedule).

Although suspend and resume can be very convenient to suspend and wake up threads, because using these two methods may cause some unpredictable things to happen, these two methods are marked as deprecated (protest) mark, which indicates that in the These two methods may be removed in future jdk versions, so try not to use these two methods to manipulate threads. The following code demonstrates the use of sleep, suspend and resume methods.

copy code
package cn.thread;

public class MyThread extends Thread {
    class SleepThread extends Thread {
        public void run() {
            try {
                sleep(2000);
                System.out.println("sleep 2s");
            } catch (Exception e) {
                e.printStackTrace ();
            }
        }
    }

    public void run() {
        while (true)
            System.out.println(new java.util.Date().getTime());
    }

    public static void main(String[] args) throws Exception {
        MyThread thread = new MyThread();
        SleepThread sleepThread = thread.new SleepThread();
        sleepThread.start(); // start running thread sleepThread
        sleepThread.join(); // delay thread sleepThread for 2 seconds
        thread.start();
        boolean flag = false;
        while (true) {
            sleep(5000); // delay the main thread for 5 seconds
            System.out.println("sleep 5s");
            flag = !flag;
            if (flag)
                thread.suspend(); //suspend the thread
            else
                thread.resume(); //Wake up the thread
        }
    }
}
copy code

On the surface, the effect of using sleep and suspend is similar, but the sleep method is not equivalent to suspend. The biggest difference between them is that one thread can suspend another thread through the suspend method. For example, in the above code, the thread thread is suspended in the main thread. And sleep only works on the currently executing thread. In the above code, sleepThread and the main thread sleep for 2 seconds and 5 seconds, respectively. Be careful when using sleep, you can't sleep another thread in one thread. For example, using the thread.sleep(2000) method in the main method cannot make the thread thread sleep for 2 seconds, but can only make the main thread sleep for 2 seconds.

There are two points to note when using the sleep method:

1. The sleep method has two overloaded forms, one of which can be set not only to milliseconds, but also to nanoseconds (1,000,000 nanoseconds equals 1 millisecond). But the Java virtual machine on most operating system platforms cannot be accurate to nanoseconds, so if nanoseconds are set for sleep, the Java virtual machine will take the nearest millisecond to this value.

2. You must use throws or try{...}catch{...} when using the sleep method. Because the run method cannot use throws, it can only use try{...}catch{...}. Sleep throws an InterruptedException when the thread is interrupted using the interrupt method (discussed in 2.3.3) while the thread is sleeping. The sleep method is defined as follows:
public static void sleep(long millis) throws InterruptedException 
public static void sleep(long millis, int nanos) throws InterruptedException

Three,
three ways to terminate the thread There are three ways to terminate the thread.
1. Use the exit flag to make the thread exit normally, that is, the thread terminates when the run method completes.
2. Use the stop method to forcibly terminate the thread (this method is not recommended, because stop is the same as suspend and resume, and unpredictable results may also occur).
3. Use the interrupt method to interrupt the thread.

1. Use the exit flag to terminate the thread
When the run method finishes executing, the thread exits. But sometimes the run method never ends. For example, using threads in the server program to monitor client requests, or other tasks that need to be processed in a loop. In this case, it is common to put these tasks in a loop, such as a while loop. If you want the loop to run forever, you can use while(true){...} to handle it. But to make the while loop exit under a certain condition, the most direct way is to set a boolean type flag, and control whether the while loop exits by setting this flag to true or false. An example of terminating a thread with the exit flag is given below.

copy code
package cn.thread;

/**
 *
 *
 * @author Lin Jiqin
 * @version 1.0 2013-7-23 2:14:00 PM
 */
public class ThreadFlag extends Thread{
    public volatile boolean exit = false;

    public void run() {
        while (!exit)
            ;
    }

    public static void main(String[] args) throws Exception {
        ThreadFlag thread = new ThreadFlag();
        thread.start();
        sleep(5000); // main thread delays for 5 seconds
        thread.exit = true; // terminate the thread thread
        thread.join();
        System.out.println("Thread exit!");
    }
}
copy code

An exit flag exit is defined in the above code. When exit is true, the while loop exits, and the default value of exit is false. When defining exit, a Java keyword volatile is used. The purpose of this keyword is to synchronize exit, that is to say, only one thread can modify the value of exit at the same time.

2. Use the stop method to terminate the thread
Use the stop method to forcibly terminate a running or suspended thread. We can use the following code to terminate the thread:
thread.stop();
Although using the above code can terminate the thread, using the stop method is very dangerous, like turning off the power of the computer suddenly, instead of shutting down according to the normal procedure, it may be Can produce unpredictable results, therefore, it is not recommended to use the stop method to terminate the thread.

3. Use the interrupt method to terminate the thread

Using the interrupt method to terminate threads can be divided into two cases:

(1) The thread is in a blocked state, such as using the sleep method.

(2) Use while(!isInterrupted()){...} to determine whether the thread is interrupted.

Using the interrupt method in the first case, the sleep method will throw an InterruptedException exception, while in the second case the thread will exit directly. The code below demonstrates the use of the interrupt method in the first case.

copy code
package cn.thread;

public class ThreadInterrupt extends Thread {
    public void run() {
        try {
            sleep(10000); // delay 10 seconds
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }

    public static void main(String[] args) throws Exception {
        Thread thread = new ThreadInterrupt();
        thread.start();
        System.out.println("Press any key within 10 seconds to interrupt the thread!");
        System.in.read();
        thread.interrupt();
        thread.join();
        System.out.println("Thread has exited!");
    }
}
copy code

After calling the interrupt method, the sleep method throws an exception and then outputs the error message: sleep interrupted.

Note: There are two methods in the Thread class to determine whether the thread is terminated by the interrupt method. One is the static method interrupted(), and the other is the non-static method isInterrupted(). The difference between these two methods is that interrupted is used to determine whether the current line is interrupted, and isInterrupted can be used to determine whether other threads are interrupted. Therefore, while (!isInterrupted()) can also be replaced by while (!Thread.interrupted()).

The above is the life cycle of a thread. To learn Java multithreading further, it is necessary to have a sufficient understanding of the Java thread life cycle.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324867631&siteId=291194637