Java中線程狀態轉換-Thread state in java


前言:本文解決的問題

  • 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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM