上一篇文章我們聊了多執行緒的基礎內容,比如為什么要使用多執行緒,執行緒和行程之間的不同,以及創建執行緒的 4 種方式,本文已收錄至我的 Github: https://github.com/xiaoqi6666/NYCSDE
今天我們來說一下執行緒的生命周期和常用 APIs:我們需要非常清楚的知道執行緒的各種狀態,比如排查程式運行慢的原因時,就需要看下是不是哪里被阻塞了;另外它也是面試時非常喜歡問的,如果基礎內容都答不好,恐怕直接就掛了,
本文分為兩大部分,
執行緒的 6 大狀態; 多執行緒常用的 APIs: join() wait() notify() yield() sleep() currentThread() getName() getId() getPriority() setPriority() stop()
執行緒狀態
關于執行緒的狀態,網上各種說法都有,比較流行的是 5 種或者 6 種,關于 5 種狀態的那個版本我沒有找到理論依據,如果有小伙伴清楚的也歡迎留言指出,
我這里所寫的是根據 java.lang.Thread 的原始碼,執行緒有以下 6 大狀態:
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITTING,
TIMED_WAITTING,
TERMINATED;
}
先上圖,我們再依次來看,

1. New
A thread that has not yet started is in this state.
就是指執行緒剛創建,還沒啟動的時候,比如剛 new 了一個 thread,
MyThread myThread = new MyThread();
2. Runnable
A thread is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.
那么接下來,自然就是要啟動執行緒了,也就是呼叫 thread 的 start() 方法,
myThread.start();
啟動之后,執行緒就進入了 Runnable 狀態,
此時所有的執行緒都會添加到一個等待佇列里,等待“CPU 調度”,
如果搶占到 CPU 的資源,那就執行;如果沒搶到,就等著唄,等當前正在執行的執行緒完成它能執行的時間片之后,再次搶占,
要注意這里在等待的一般是系統資源,而不是鎖或者其他阻塞,
3. Blocked
Thread state for a thread blocked waiting for a monitor lock.
A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after callingwait()Object.
這里給出了非常明確的 use case,就是被鎖在外面的才叫阻塞,所以這里必須要有至少 2 個執行緒,
4. Waiting
A thread in the waiting state is waiting for another thread to perform a particular action.
那具體有哪些原因呢?
A thread is in the waiting state due to calling one of the following methods:
Object.wait with no timeout Thread.join with no timeout LockSupport.park
所以說,當呼叫了
wait(),join(),park()
方法之后,執行緒進入等待狀態,
這里的等待狀態是沒有時間限制的,可以無限的等下去... 所以需要有人來喚醒:
如果是通過 wait()進入等待狀態的,需要有notify()或者notifyAll()方法來喚醒;如果是通過 join()進入等待狀態的,需要等待目標執行緒運行結束,
比如在生產者消費者模型里,當沒有商品的時候,消費者就需要等待,等待生產者生產好了商品發 notify(),下一篇文章我們會細講,
5. Timed_waiting
導致這個狀態的原因如下:
Thread.sleep Object.wait with timeout Thread.join with timeout LockSupport.parkNanos LockSupport.parkUntil
其實就是在上一種狀態的基礎上,給了具體的時間限制,
那么當時間結束后,執行緒就解放了,
6. Terminated
A thread that has exited is in this state.
這里有 3 種情況會終止執行緒:
執行完所有代碼,正常結束; 強制被結束,比如呼叫了 stop()方法,現在已經被棄用;拋出了未捕獲的例外,
執行緒一旦死亡就不能復生,
如果在一個死去的執行緒上呼叫 start() 方法,那么程式會拋出 java.lang.IllegalThreadStateException,
接下來我們說說多執行緒中常用的 11 個 APIs,
APIs
1. join()
join() 方法會強制讓該執行緒執行,并且一直會讓它執行完,
比如上一篇文章的例子是兩個執行緒交替執行的,那么我們這里該下,改成呼叫小齊執行緒.join(),那么效果就是先輸出 小齊666,
public class MyRunnable implements Runnable {
@Override
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("小齊666:" + i);
}
}
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new MyRunnable());
t.start();
t.join();
for(int i = 0; i < 100; i++) {
System.out.println("主執行緒" + i + ":齊姐666");
}
}
}

所以 join() 能夠保證某個執行緒優先執行,而且會一直讓它執行完,再回歸到公平競爭狀態,
join() 方法其實是用 wait() 來實作的,我們來看下這個方法,
2. wait() and notify()
wait() 其實并不是 Thread 類的方法,而是 Object 里面的方法,
該方法就是讓當前物件等待,直到另一個物件呼叫 notify() 或者 notifyAll(),
當然了,我們也可以設定一個等待時長,到時間之后物件將會自動蘇醒,
4. yield()
yield 本身的中文意思是屈服,用在這里倒也合適,
yield() 表示當前執行緒主動讓出 CPU 資源一下,然后我們再一起去搶,
注意這里讓一下真的只是一下,從“執行中”回到“等待 CPU 分配資源”,然后所有執行緒再一起搶占資源,
5. sleep()
顧名思義,這個方法就是讓當前執行緒睡一會,比如說,
myThread.sleep(1000); // 睡眠 1 秒鐘
它會拋出一個 InterruptedException 例外,所以還要 try catch 一下,
6. currentThread()
Returns a reference to the currently executing thread object.
該方法是獲取當前執行緒物件,
注意它是一個 static 方法,所以直接通過 Thread 類呼叫,
比如列印當前執行緒
System.out.println(Thread.currentThread());
前文的例子中,它會輸出:
Thread[Thread-0,5,main]
Thread[main,5,main]
沒錯,它的回傳值也是 Thread 型別,
7. getName()
該方法可以獲取當前執行緒名稱,
這個名稱可以自己設定,比如:
Thread t = new Thread(new MyRunnable(), "壹齊學");
8. getId()
該方法是獲取執行緒的 Id.
9. getPriority()
執行緒也有優先級的哦~
雖然優先級高的執行緒并不能百分百保證一定會先執行,但它是有更大的概率被先執行的,
優先級的范圍是 1-10,我們來看原始碼:
/**
* The minimum priority that a thread can have.
*/
public final static int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
public final static int NORM_PRIORITY = 5;
/**
* The maximum priority that a thread can have.
*/
public final static int MAX_PRIORITY = 10;
如果不在這個范圍,JDK 拋出 IllegalArgumentException() 的例外,
10. setPriority()
當然啦,我們也是可以自己設定某個執行緒的優先級的,
設定的優先級也需要在規定的 1-10 的范圍內哦,如果不在這個范圍也會拋例外,
11. stop()
最后我們來說下 stop() 方法,也是前文提到過的強制停止執行緒的一種方式,但現在已被棄用,因為會引起一些執行緒安全方面的問題,
好了,以上就是有關執行緒狀態和常用 API 的介紹了,相信大家看完之后對執行緒的整個流程應該有了清晰的認識,其實里面還有很多細節我沒有展開,畢竟這是多執行緒的第 2 講,更深入的內容我們慢慢來,
如果你喜歡這篇文章,記得給我點贊留言哦~你們的支持和認可,就是我創作的最大動力,我們下篇文章見!
我是小齊,紐約程式媛,終生學習者,每天晚上 9 點,云自習室里不見不散!
**更多干貨文章見我的 Github: https://github.com/xiaoqi6666/NYCSDE
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/226580.html
標籤:其他
上一篇:BUUCTF SSTI
