Preface
In the daily development process , If we need to execute some time-consuming procedures , Generally speaking, a new thread is started , Put the time-consuming code in the thread , Then start thread execution . But threads consume system resources , If there are multiple threads running at the same time , Preempt system resources from each other , That would certainly put a tremendous strain on the system . therefore , How to manipulate threads , It is important to ensure that the overall functionality of the application is not affected , This requires us to understand the life cycle of the thread .
The life cycle of a thread
The life cycle of a thread is 6 States , Namely NEW( newly build )、RUNNABLE( Can run )、BLOCKED( Blocked )、 WAITING( wait for )、TIMED_WAITING( Time wait for )、TERMINATED( Terminated ), stay Thread Source code State All are defined in the enumeration :
public static enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
private State() {
}
}
1、NEW The status represents the thread that was just created , The thread is not yet running , So it hasn’t been implemented start() Method , It is also easier to create threads , You can refer to 《Java Concurrent programming :Java There are three ways to create a thread 》.
2、 When the thread executes , be in RUNNABLE state , Indicates that the resources required for the thread are ready .
3、 If the thread is blocked during execution , For example, in a program in a thread synchronized Synchronization code block , The thread will pause , Go into blocking mode , Until the requested lock is obtained , This is where the thread is BLOCKED state .
The example code is as follows :
public class ThreadDemo {
public static Object testObject = new Object();
public static class MyThread extends Thread {
public MyThread(String name) {
super.setName(name);
}
@Override
public void run() {
// Every run run Methods need to be obtained testObject object
synchronized (testObject) {
System.out.println("thread name:" + this.getName());
//.............. The long-running ..............
}
}
}
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
new MyThread(" Threads "+i).start();
}
}
}
In the code above , Thread run Methods need to be fetched before a time-consuming program can be executed testobject The lock of the object , Because object locks are public objects , therefore , Multiple threads running simultaneously , Only one thread can acquire the lock at a time , Let’s say that at some point A Threads Acquire the lock , Other threads are in a blocking state waiting for the lock to be released , The program cannot continue to execute until the lock is acquired , So that’s threaded BLOCKED state .
4、WAITING Represents the waiting state , be in WAITING The thread of state will enter one Unlimited time The waiting for , Once you’ve waited for the expected event , The thread will execute again , Get into RUNNABLE state . The most typical scenario is this wait for (wait) and notice (notify).
The method for the wait state is wait(), And notice is notify(), These two methods do not belong Thread class , But to Object class , So all objects can use both methods . When an object instance obj call wait() After the method , The current thread will wait on this object , Until another thread calls it obj.notify() until . The object instance at this point obj It ACTS as a communication tool between multiple threads . The example code is as follows :
public class ThreadDemo {
public static Object testObject = new Object();
public static class MyThread1 extends Thread {
@Override
public void run() {
synchronized (testObject) {
System.out.println("MyThread1 wait :" + System.currentTimeMillis());
try {
// call wait Method enters the wait state
testObject.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static class MyThread2 extends Thread {
@Override
public void run() {
synchronized (testObject) {
System.out.println("MyThread2 start notify :" + System.currentTimeMillis());
//.............. The long-running ..............
// A notice , Wakes up the waiting thread
testObject.notify();
}
}
}
public static void main(String[] args) {
MyThread1 t1 = new MyThread1();
MyThread2 t2 = new MyThread2();
t1.start();
t2.start();
}
}
5、TIMED_WAITING and WAITING equally , Both are waiting states , but TIMED_WAITING There will be a A time-bound wait . There are several methods for manipulating thread state with timeout parameters , The thread calling the method enters a timing wait state . This state will remain until the timeout expires or appropriate notification is received , The most common application is the call Thread.sleep() Method .
The example code is as follows :
public static class MyThread extends Thread {
@Override
public void run() {
System.out.println("MyThread start :" + System.currentTimeMillis());
try {
// Sleep for two seconds
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("MyThread end :" + System.currentTimeMillis());
}
}
public static void main(String[] args) {
MyThread t = new MyThread1();
t.start();
}
After starting the thread , Program run to Thread.sleep() The method will sleep , The time is determined by parameters , In milliseconds , So execute main After the method , The latter output appears every two seconds .
MyThread start :1544704974271
MyThread end :1544704976272
6、 When the thread is finished executing , Get into TERMINATED state , End of the said , Threads are typically terminated for two reasons :
-
run The method dies when it works .
-
An exception that was not caught terminated run Methods leading to accidental death .
Okay , The life cycle of a thread is summed up , Let me draw a picture that looks something like this :