java多線程基礎(chǔ)(六)

今天繼續(xù)回到Java多線程的基礎(chǔ)問題上。今天主要想說一下:線程的狀態(tài)

在這里需要說一下,由于剛開始寫文章不久,總是想到什么就寫什么,可能就會出現(xiàn)基礎(chǔ)講講,跳到進階,然后又跑到基礎(chǔ),而且內(nèi)容里面的表達(dá)可能也不是很準(zhǔn)確,希望大家能夠原諒。我會慢慢改進,后面如果寫系列文章的話會先做一個整體的規(guī)劃。盡量不要像現(xiàn)在這么亂了。好了不說了,再說就變成水文了。

線程的狀態(tài)

開局一張圖,內(nèi)容全靠水。。。

線程狀態(tài).png
  • new(新建狀態(tài)):當(dāng)我們新new一個線程后,這個線程就是新建狀態(tài)Thread t = new Thread()
  • ready(就緒狀態(tài)):new了一個線程,調(diào)用線程的start()方法后,這個線程將會進入就緒狀態(tài),這個時候他只是具備了可執(zhí)行的條件,但是還是沒有執(zhí)行
  • running(執(zhí)行狀態(tài)):就緒狀態(tài)中的線程其實是被扔到了CPU的等待隊列排對等待翻牌子去了。等到CPU翻到了誰的牌子,誰就進入了執(zhí)行狀態(tài)。學(xué)過了yield之后我們都知道,調(diào)用它會讓執(zhí)行狀態(tài)的線程直接讓出當(dāng)前CPU跑到就緒狀態(tài)繼續(xù)排隊
  • blocking(阻塞狀態(tài)):當(dāng)我們在線程中使用了synchronized關(guān)鍵字時,當(dāng)代碼運行到這里是需要獲取鎖之后才能繼續(xù)執(zhí)行,這種狀態(tài)叫做阻塞狀態(tài),由于阻塞時候CPU就會放棄你,所以當(dāng)我獲取到鎖之后我才會進入到就緒狀態(tài)再去排隊等待CPU翻牌子
  • waitting(等待狀態(tài)):當(dāng)運行中的線程調(diào)用了wait(),join(),park()方法后,線程會等待其他線程執(zhí)行完成或者使用其他的方法來喚醒才能繼續(xù)進入執(zhí)行狀態(tài)
  • timeWaitting(有時間等待狀態(tài)):當(dāng)運行中的線程調(diào)用了sleep(tiem)和調(diào)用上訴的方法帶上時間,線程會在那里等待直到時間結(jié)束就會自動進入執(zhí)行狀態(tài)
  • over(結(jié)束狀態(tài)):當(dāng)一個線程正常執(zhí)行完成,或者上訴所有狀態(tài)運行過程中拋出異?;蛘{(diào)用interrupt方法都會讓線程進入到結(jié)束狀態(tài)。當(dāng)線程進入結(jié)束狀態(tài)后就無法再進行其他的狀態(tài)轉(zhuǎn)換,只有重新new才可以重新運行

我們可以通過簡單的小程序來看到部分的線程狀態(tài):

public class ThreadStateTest {

    static class MyThread extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(3000);
                 System.out.println("sleep 之后的狀態(tài):" + Thread.currentThread().getState());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        System.out.println("new 之后的狀態(tài):" + myThread.getState());
        myThread.start();
        System.out.println("start 之后的狀態(tài):" + myThread.getState());
        myThread.join();//等待線程去死
        System.out.println("join 之后的狀態(tài):" + myThread.getState());
    }
}

注意

有一點需要注意,調(diào)用Lock的一些方法并不會讓線程進入blocked狀態(tài),而是會讓線程進入waitting狀態(tài)。

public class LockTests {

    Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        LockTests lockTest = new LockTests();
        // 可重入鎖 + 基本使用 案例開始
        for (int i = 0;i<3;i++) {
            new Thread(()->{lockTest.tryLockTest();}, "線程 " + i).start();
        }
    }

    public synchronized void tryLockTest(){
        try {
            try {
                Thread.sleep(10000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

在他執(zhí)行的時候,我們使用jstack -l pid 命令就可以看到如下圖的樣子:

[圖片上傳失敗...(image-645e24-1698156369246)]

可以看到,沒有獲取到鎖的線程的狀態(tài)是blocked 的沒有問題,而且也看出了synchronized關(guān)鍵字實現(xiàn)鎖的方式是使用monitor

再看下面一個小程序:

public class LockTests {

    Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        LockTests lockTest = new LockTests();
        // 可重入鎖 + 基本使用 案例開始
        for (int i = 0;i<3;i++) {
            new Thread(()->{lockTest.tryLockTest();}, "線程 " + i).start();
        }
    }

    public void tryLockTest(){
        try {
            if (lock.tryLock(50, TimeUnit.SECONDS)) {
                try {
                    Thread.sleep(10000);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

由于我們使用的是tryLock(time) 所以沒有獲取到鎖的狀態(tài)是timed_waitting 可以看到他鎖定的方式是使用park,這個我準(zhǔn)備下一篇會說一下。他是locksupport工具類里面的方法。

總結(jié)

本篇文章總共講了線程的7中狀態(tài):new、runnable、running、blocking(blocked)、waitting、time_waitting、over(dead)

順便提了一個小的排查線程問題的工具:jstack

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容