java線程的狀態(tài)變換

下面將會針這張圖對線程的狀態(tài)轉(zhuǎn)換來做解釋


圖片.png

在操作系統(tǒng)的課程中把線程大致分為了3個(gè)狀態(tài)
1.就緒狀態(tài)(線程對資源上鎖,但未分配時(shí)間片,等待cpu分配,隨時(shí)可以運(yùn)行)
2.運(yùn)行狀態(tài)(線程對資源上鎖,并擁有了時(shí)間片,正在運(yùn)行中)
3.阻塞狀態(tài)(在運(yùn)行狀態(tài)下缺失了某種資源導(dǎo)致運(yùn)行暫停,也可以是被cpu強(qiáng)制暫停)

java中多了新建和死亡狀態(tài),新建狀態(tài)(new)就是線程定義好了之后,還沒調(diào)用start方法告訴操作系統(tǒng)。死亡狀態(tài)就是run方法執(zhí)行完,也就是線程操作完畢。這兩個(gè)狀態(tài)很容易理解。

就緒----->運(yùn)行很簡單,分配時(shí)間片就行,這個(gè)不需要我們擔(dān)心,
運(yùn)行----->就緒就不簡單了,因?yàn)橹虚g可能存在阻塞態(tài)

(1)運(yùn)行----->就緒
這個(gè)狀態(tài)變換是由于線程失去時(shí)間片,可以使用.yield()實(shí)現(xiàn)


圖片.png

使用yield()后線程短暫停,暫停由系統(tǒng)決定的毫秒級時(shí)間,線程不釋放鎖,僅剝奪時(shí)間片,所以線程暫停結(jié)束后進(jìn)入就緒狀態(tài)

(2)運(yùn)行----->阻塞------>就緒
1)不釋放鎖的阻塞
包括sleep,join方法
sleep()方法


圖片.png

我們看到sleep()方法描述暫停一定時(shí)間后恢復(fù)就緒狀態(tài),不釋放鎖,時(shí)間結(jié)束后進(jìn)入就緒狀態(tài)。跟yield很像,那為什么sleep算阻塞呢,原因是sleep()的暫停時(shí)間是系統(tǒng)和用戶一起決定的,用戶可以設(shè)定休眠很長時(shí)間,比如一分鐘,我們知道線程的運(yùn)行都是毫秒級別的,這樣一比sleep自然就屬于了阻塞。

join()
這個(gè)方法讓調(diào)用該方法的線程優(yōu)先執(zhí)行,通常設(shè)置在另一個(gè)線程的run()方法中

class Father extends Thread{
    
    public void run() {
        Thread son=new Son();
        son.start();
        try {
            son.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class Son extends Thread{
    
    public void run() {
        
    }
}

在上面的代碼中我們希望Son先執(zhí)行,我們可以在Father中實(shí)現(xiàn)son.join()來讓
son插隊(duì)到Father線程的前面執(zhí)行,那么對Father來說,就相當(dāng)于被插隊(duì),此時(shí)阻塞,當(dāng)插隊(duì)的son執(zhí)行完后Father并不立即執(zhí)行,而是回到就緒狀態(tài),等待cpu時(shí)間片

需要注意的是,操作系統(tǒng)控制的線程遇到類似I/O操作這類等待臨界資源導(dǎo)致的阻塞也是不釋放鎖的阻塞,在拿到臨界資源的鎖后就緒,隨時(shí)可以運(yùn)行,但這也使得多個(gè)線程占據(jù)不同的鎖,容易引起死鎖

(2)釋放鎖的阻塞
wait()和wait(long ,int)
wait()方法使線程失去時(shí)間片,失去鎖,并被冷藏,直到使用notify()/notifyAll()喚醒
notify()喚醒單個(gè)線程,notifyAll()喚醒所有
wait(long,int)和上面基本一樣,唯一不同的是這里可以設(shè)置一個(gè)參數(shù)為時(shí)間,在notify()喚醒前如果時(shí)間耗盡會自動蘇醒,不必等notify
另外,interrupt()也可以用在這里改變線程狀態(tài)

喚醒后的線程依然是阻塞狀態(tài),和喚醒前不同的是線程可以去爭奪資源鎖,此時(shí)就類似遇到同步鎖而被動阻塞線程,在獲取了所有鎖之后就進(jìn)入就緒狀態(tài),隨時(shí)可以運(yùn)行。

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

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

  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 3,115評論 1 18
  • 本文主要講了java中多線程的使用方法、線程同步、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等。 首先講...
    李欣陽閱讀 2,602評論 1 15
  • 林炳文Evankaka原創(chuàng)作品。轉(zhuǎn)載自http://blog.csdn.net/evankaka 本文主要講了ja...
    ccq_inori閱讀 738評論 0 4
  • 該文章轉(zhuǎn)自:http://blog.csdn.net/evankaka/article/details/44153...
    加來依藍(lán)閱讀 7,472評論 3 87
  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對應(yīng)一個(gè)進(jìn)程,當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行時(shí),即變成一個(gè)進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    勝浩_ae28閱讀 5,259評論 0 23

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