前言:本文解決的問題
- java中的線程有哪些狀態
- 這些狀態怎么轉換
1 Java中線程的狀態
在任何時候JAVA中的線程總處於以下Thread.State枚舉類6種狀態中的一種:
- New,任何線程被新建后就處於該狀態
- Runnable , 當調用start()方法后線程的狀態
- Waiting,等待另一個線程執行動作,比如當前線程調用join(),另一線程的狀態
- Timed-waiting,正在等待另一個線程執行動作達到指定等待時間的線程處於此狀態;比如某一線程調用sleep();
- Termanated,已經退出的線程的狀態
注意
線程處於Runnable狀態,並不一定是正在運行,而是取決於線程調度器。
2 狀態轉換
2.1 NEW
新建一個線程還沒執行時,線程就處於NEW狀態
obj = new ThreadStateTest();
thread1 = new Thread(obj); //使用new 新建
對應的枚舉類為——public static final Thread.State NEW
2.2 RUNNABLE
thread1.start();
當啟動star()方法后線程處於該狀態——public static final Thread.State RUNNABLE
2.3 BLOCKED
線程A和線程B都需要持有lock對象的鎖才能調用方法。如果A持有鎖,那么線程B處於BLOCKED;如果線程B持有鎖,那么線程A處於public static final Thread.State BLOCKED狀態。
2.4 WAITING
thread2.join();
Object的wait方法、Thread的join方法(都是沒有時間參數的)和LockSupport.park 都會產生 public static final Thread.State WAITING狀態。處於該狀態的線程,正在等待另一線程執行特定的操作;比如wait()等待別的線程喚醒,join()等待調用該方法的線程結束。
2.5 TIMED-WAITING
Thread.sleep(200);
和上一狀態類似,是一個有等待時間的等待狀態public static final Thread.State TIMED_WAITING, 線程處於定時等待狀態,不會一直等下去。
2.6 TERMINATED
線程運行結束后(因為run方法正常退出而自然死亡;由於沒有捕獲的異常終止了run方法而導致不正常死亡),就處於該狀態public static final Thread.State TERMINATED。
狀態轉移總結
從NEW變為RUNNABLE,調用start()方法;當線程處於RUNNABLE,如果沒有獲得必須的鎖,則被阻塞,進入BLOCKED狀態;在BLOCKED狀態的線程獲得鎖后變為RUNNABLE;處於RUNNABLE狀態的線程當調用sleep(1000)方法時進入TIMED-WAITING狀態;當某一線程調用join()方法時,另一線程處於WAITING狀態;當線程正常運行結束后處於TERMINATED狀態。下面看完整的代碼。
3 例子分析
class thread implements Runnable{
@Override
public void run() {
try {
Thread.sleep(1500);
}catch(InterruptedException e){
e.printStackTrace();
}
try {
Thread.sleep(1500);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("State of thread1 while it called join on thread2 -"+
ThreadStateTest.thread1.getState());
try {
Thread.sleep(200);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
public class ThreadStateTest implements Runnable{
public static Thread thread1;
public static ThreadStateTest obj;
public static void main(String[] args) {
obj = new ThreadStateTest();
thread1 = new Thread(obj);
System.out.println("State of thread1 after creating it - "+ thread1.getState());
thread1.start();
System.out.println("State of thread1 after calling .start method on it -"+ thread1.getState());
}
@Override
public void run() {
thread myThread = new thread();
Thread thread2 = new Thread(myThread);
//thread1 created and is currently in the NEW state
System.out.println("State of thread2 after creating it - "+ thread2.getState());
thread2.start();
System.out.println("State of thread2 after calling .start() - "+ thread2.getState());
//moving thread1 to timed waiting state
try {
Thread.sleep(200);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("State of thread2 after calling .sleep method on it - "+thread2.getState());
try {//waiting thread2 to die
thread2.join();
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("State of thread 2 when it has finished it's execution - "+ thread2.getState());
}
}
執行結果
State of thread1 after creating it - NEW
State of thread1 after calling .start method on it -RUNNABLE
State of thread2 after creating it - NEW
State of thread2 after calling .start() - RUNNABLE
State of thread2 after calling .sleep method on it - TIMED_WAITING
State of thread1 while it called join on thread2 -WAITING
State of thread 2 when it has finished it's execution - TERMINATED
結果分析
當一個線程新建時,處於NEW狀態;當調用.start()后,線程調度器把它變成RUNNABLE狀態。當thread2調用.join()方法時,當前正在執行這個命令的線程thread1將會等待thread2滅亡(die),因此thread1的狀態時WAITING。
Whenever join() method is called on a thread instance, the current thread executing that statement will wait for this thread to move to Terminataed state.
參考網站
https://fangjian0423.github.io/2016/06/04/java-thread-state/
https://www.journaldev.com/1044/thread-life-cycle-in-java-thread-states-in-java
https://www.geeksforgeeks.org/lifecycle-states-of-a-thread-in-java/