前言
上篇文章講解了多線程的停止方法。我們本篇文章來講講多線程的運行狀態。
一、多線程的運行狀態。
我們都知道,線程分爲新建、就緒、運行、阻塞、死亡這幾種狀態,這些狀態分別是什麼意思呢,來看一下。
新建:指的是線程新創建出來,並沒有運行start方法,這時候就是新建狀態,沒有運行代碼。
就緒:就緒狀態指的是線程調用了start方法,線程準備就緒,爭搶cpu,當搶到cpu的時候,纔可以進行執行代碼。因爲在單CPU的計算機系統中,不可能同時運行多個線程,一個時刻僅有一個線程處於運行狀態。因此此時可能有多個線程處於就緒狀態。
運行:運行值得是線程搶到了cpu的後,進入運行狀態,執行run方法, 開始實際的代碼運行。
阻塞:阻塞狀態是線程運行中,由於某些原因進入阻塞狀態。例如線程通過sleep方法進入睡眠狀態,等待觸發某個條件。阻塞狀態就是正在運行的線程沒有結束,暫時讓出cpu,這時候其他處於運行狀態的線程就可以獲取cpu,進入運行狀態。
死亡:死亡狀態是指線程run()、main() 方法執行結束,或者因異常退出了run()方法,則該線程結束生命週期。死亡的線程不可再次復生。
二、線程狀態的變化
線程的狀態變化如下:
其中涉及到了yield方法和join方法,來講解一下。
yield方法是:暫停當前執行的線程,放棄cpu資源,執行其他線程。是讓線程從運行狀態回到可運行狀態,但是實際無法保證yield()可以達到讓步的目的,因爲當前線程可以能會再次搶佔到CPU。在大多數情況下,yield()將導致線程從運行狀態轉到可運行狀態,但有可能沒有效果
join方法是:Join把指定的線程加入到當前線程,可以把交替執行的兩個線程合併爲順序執行,例如線程B調用線程A的join方法,那麼將先執行完A線程,纔會執行線程B,如下面代碼所示
/**
* @version 1.0
* @Description joinDemo
* @Author wb.yang
*/
public class JoinDemo {
/**
* 女神
*/
static class Goddess implements Runnable {
private Thread thread;
public Goddess(Thread thread) {
this.thread = thread;
}
@Override
public void run() {
System.out.println("Goddess開始排隊打飯.....");
try {
if (thread != null) {
thread.join();
}
} catch (InterruptedException e) {
}
//休眠2秒
SleepTools.second(2);
System.out.println(Thread.currentThread().getName()
+ " Goddess打飯完成.");
}
}
/**
* 女神的男朋友
*/
static class GoddessBoyfriend implements Runnable {
@Override
public void run() {
//休眠2秒
SleepTools.second(2);
System.out.println("GoddessBoyfriend開始排隊打飯.....");
System.out.println(Thread.currentThread().getName()
+ " GoddessBoyfriend打飯完成.");
}
}
public static void main(String[] args) throws Exception {
// 女神的男朋友
GoddessBoyfriend goddessBoyfriend = new GoddessBoyfriend();
Thread gbf = new Thread(goddessBoyfriend);
// 女神,把女神的男朋友線程放入女神中
Goddess goddess = new Goddess(gbf);
// 湯姆
Thread tom = new Thread(goddess);
tom.start();
gbf.start();
System.out.println("湯姆開始排隊打飯.....");
tom.join();
//讓主線程休眠2秒
SleepTools.second(2);
System.out.println(Thread.currentThread().getName() + " 湯姆打飯完成.");
}
}
從代碼中可以看出總共有三個線程,湯姆,女神,女神男朋友三個線程,如果正常的線程的話,執行順序是不一定的,就是說這個是那個線程都有可能先執行完,然後看看執行結果把。
從結果中看出,線程是有執行順序的,這就是因爲我們用了join方法,在湯姆的線程中調用了女神線程的join方法,所以湯姆線程就要等待女神線程先執行完畢,而在女神線程中,有調用的女神男朋友的線程,所以又要等待女神男朋友線程的執行完畢,所以最終結果就是女神男朋友先打完飯,然後是女神,最後是湯姆。這就是join方法的作用。
總結
1.線程的五種狀態,新建、就緒、運行、阻塞、死亡
2.線程的兩個方法,yield和join方法