Just like people are born, old, sick and die, threads also have to go through four different states: starting (waiting), running, hanging and stopping. These four states can be controlled through methods in the Thread class. The methods related to these four states in the Thread class are given below.
// Suspend and wake up threads
public void resume( ); // Not recommended for use
public void suspend( ); // Not recommended for use
public static void sleep(long millis);
public static void sleep(long millis, int nanos);
// Terminate thread
public void stop( ); // Not recommended for use
public void interrupt( );
// Get thread status
public boolean isAlive( );
public boolean isInterrupted( );
public static boolean interrupted( );
// join method
public void join( ) throws InterruptedException;
The thread does not execute the code in the run method immediately after it is established, but is in a waiting state. When the thread is in the waiting state, you can set various attributes of the thread through the methods of the Thread class, such as the thread's 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 in the running state, isAlive returns true. When isAlive returns false, the thread may be in the waiting state or in the 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.
public class LifeCycle extends Thread
{
public void run()
{
int n = 0;
while ((++n) < 1000);
}
public static void main(String[] args) throws Exception
{
LifeCycle thread1 = new LifeCycle();
System.out.println("isAlive: " + thread1.isAlive());
thread1.start();
System.out.println("isAlive: " + thread1.isAlive());
thread1.join(); // Wait for thread thread1 to end before continuing execution
System.out.println("thread1 has ended!");
System.out.println("isAlive: " + thread1.isAlive());
}
}
The result of running the above code:
Once the thread starts executing the run method, it will not exit until the run method is completed. However, during the execution of the thread, there are two methods that can be used to temporarily stop the thread execution. These two methods are suspend and sleep. After using suspend to suspend the thread, you can wake up the thread through 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 execute immediately, but only enters the ready state, waiting for the system to schedule).
Although suspend and resume can easily suspend and wake up threads, using these two methods may cause some unpredictable things to happen. Therefore, these two methods are marked as deprecated (protest), which indicates that in These two methods may be deleted in future jdk versions, so try not to use these two methods to operate threads. The following code demonstrates the use of sleep, suspend and resume methods.
public class MyThread extends Thread
{
class SleepThread extends Thread
{
public void run()
{
try
{
sleep(2000);
}
catch (Exception e)
{
}
}
}
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
flag = !flag;
if (flag)
thread.suspend();
else
thread.resume();
}
}
}
There are two points to note when using the sleep method:
1. The sleep method has two overloaded forms. One of the overloaded forms can not only set milliseconds, but also nanoseconds (1,000,000 nanoseconds is equal to 1 millisecond). However, the Java virtual machine on most operating system platforms is not accurate to nanoseconds. Therefore, if nanoseconds are set for sleep, the Java virtual machine will take the millisecond closest to this value.
2. When using the sleep method, you must use throws or try{…}catch{…}. Because the run method cannot use throws, you can only use try{…}catch{…}. When the thread is sleeping , sleep will throw an InterruptedException when interrupting a thread using the interrupt method (this method will be discussed in 2.3.3). The sleep method is defined as follows:
There are three ways to terminate a thread.
1. Use the exit flag to make the thread exit normally, that is, the thread terminates when the run method is completed.
2. Use the stop method to forcefully terminate the thread (this method is not recommended because stop, like suspend and resume, may also produce unpredictable results).
3. Use the interrupt method to interrupt the thread.
1. Terminate the thread using the exit flag
When the run method is executed, the thread will exit. But sometimes the run method never ends. For example, threads are used in server programs to monitor client requests, or other tasks that require cyclic processing. In this case, these tasks are usually placed 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 if you want to make the while loop exit under a certain condition, the most direct way is to set a boolean type flag, and set this flag to true or false to control whether the while loop exits. An example of terminating a thread using the exit flag is given below.
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); //The main thread delays for 5 seconds
thread.exit = true; // Terminate thread thread
thread.join();
System.out.println("Thread exited!");
}
}
2. Use the stop method to terminate the thread
Use the stop method to forcefully terminate a running or suspended thread. We can use the following code to terminate the thread:
3. Use the interrupt method to terminate the thread
Using the interrupt method to terminate a thread can be divided into two situations:
(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.
In the first case using the interrupt method, 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.
public class ThreadInterrupt extends Thread
{
public void run()
{
try
{
sleep(50000); // delay 50 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 50 seconds to interrupt the thread!");
System.in.read();
thread.interrupt();
thread.join();
System.out.println("The thread has exited!");
}
}
sleep interrupted
The thread has exited!
Note: There are two methods in the Thread class to determine whether the thread is terminated through 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 thread is interrupted, while isInterrupted can be used to determine whether other threads are interrupted. Therefore, while (!isInterrupted()) can also be replaced by while (!Thread.interrupted()).