摘要
- 什麼是線程排程
- 協同式排程
- 搶占式排程
- 線程優先級
- 線程狀态
1. 線程排程
1.1 什麼是線程排程
線程排程是指系統為線程配置設定處理器使用權的過程。
1.2 協同式排程
線程的執行時間由線程本身控制,線程在工作完成以後要主動通知系統切換到另一個線程上。優點是實作簡單、切換操作對線程自己可見,不存線上程同步問題;缺點是線程時間不可控制,有可能造成程式一直阻塞。
1.2 搶占式排程
線程由作業系統來配置設定執行時間,線程的切換不會由線程本身決定。優點是線程執行時間可控;缺點則是需要進行線程同步。
Java中的線程采用的是搶占式排程的實作方式。
2. 線程優先級
線程優先級是用來表示線程獲得CPU資源的可能性,線程優先級越高,系統更容易為其配置設定處理器去執行。
Java中的線程優先級不太靠譜,原因是Java定義了大約10個級别的優先級,最小的優先級為1,最高優先級為10,線程的優先級預設與父線程一緻,假設作業系統線程的優先級的級别層次比Java少(最小1,最大5),那麼在映射以後,Java兩個不同優先級的優先級有可能共同對應作業系統的同一個優先級。
3. 線程狀态
Java線程大緻有以下狀态:
- New
- Runnable
- Waiting
- TimeWaiting
- Blocked
- Terminated
3.1 New
建立以後尚未啟動的線程,new但未start。
3.2 Runnable
Runnable的線程有可能在執行,也有可能等待着CPU為它配置設定執行時間。
3.3 Waiting
線程不會被CPU配置設定執行時間,需要其他線程顯示喚醒。以下方法會讓線程進入Waiting狀态:
- 沒有Timeout的Object.wait()
- 沒有Timeout的Thread.join()
- LockSupport.park()方法
3.4 TimeWaiting
線程不會被CPU配置設定執行時間,可以被其他線程顯示喚醒,一定時間後沒有其他線程喚醒,将會由作業系統主動喚醒。以下方法會讓線程進入TimeWaiting狀态:
- Thread.sleep()
- 設定了Timeout的Object.wait()
- 設定了Timeout的Thread.join()
- LockSupport.parkNanos()
- LockSupport.parkUntil()
3.5 Blocked
線程處于阻塞狀态,阻塞狀态的線程在等待着擷取到一個排他鎖。在程式等待進入同步區域的時候,線程将進入這種狀态
3.6 Terminate
線程執行結束以後的狀态。
package jvm;
/**
* @author sh
*/
public class ThreadTest implements Runnable {
@Override
public void run() {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTest threadTest = new ThreadTest();
Thread thread = new Thread(threadTest, "TEST-1");
thread.start();
thread.join();
}
}
複制
上述代碼首先根據前文我們的描述,我們可以得出,主線程應該是Waiting(由于Thread.join()方法的調用),TEST-1線程應該是TimeWaiting狀态(通過Thread.sleep()方法的調用)。
下面我們通過jstack指令看一下我們的堆棧是不是和我們分析的結果一緻:
public class ThreadTest implements Runnable {
private final Object syncObj = new Object();
@Override
public void run() {
synchronized (syncObj) {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTest threadTest = new ThreadTest();
Thread t1 = new Thread(threadTest, "TEST-1");
Thread t2 = new Thread(threadTest, "TEST-2");
t1.start();
Thread.sleep(1L);
t2.start();
t1.join();
}
}
複制
上述這段代碼,TEST-1線程應該是TimeWaiting,TEST-2線程應該是BLOCK狀态,主線是Waiting狀态,下面我們通過jstack指令來看一下:
本期的Java線程排程和狀态實作介紹到這,我是shysh95,關注+在看+贊,你就是最靓的仔,我們下期再見!!
往期推薦
Java線程實作
Java記憶體模型(可見性有序性)
Java記憶體模型
Java學習路線
JIT即時編譯器(C1和C2)