Java多線程學(xué)習(xí)七 線程組

一、線程狀態(tài)

1. 初始(NEW)

新創(chuàng)建了一個(gè)線程對(duì)象,但還沒有調(diào)用start()方法。

2. 運(yùn)行(RUNNABLE)

Java線程中將就緒(ready)和運(yùn)行中(running)兩種狀態(tài)籠統(tǒng)的稱為“運(yùn)行”。
線程對(duì)象創(chuàng)建后,其他線程(比如main線程)調(diào)用了該對(duì)象的start()方法。該狀態(tài)的線程位于可運(yùn)行線程池中,等待被線程調(diào)度選中,獲取CPU的使用權(quán),此時(shí)處于就緒狀態(tài)(ready)。就緒狀態(tài)的線程在獲得CPU時(shí)間片后變?yōu)檫\(yùn)行中狀態(tài)(running)。

3. 阻塞(BLOCKED)

表示線程阻塞于鎖。
BLOCKED稱為阻塞狀態(tài),或者說線程已經(jīng)被掛起,它“睡著”了,原因通常是它在等待一個(gè)“鎖”,當(dāng)嘗試進(jìn)入一個(gè)synchronized語句塊/方法時(shí),鎖已經(jīng)被其它線程占有,就會(huì)被阻塞,直到另一個(gè)線程走完臨界區(qū)或發(fā)生了相應(yīng)鎖對(duì)象的wait()操作后,它才有機(jī)會(huì)去爭(zhēng)奪進(jìn)入臨界區(qū)的權(quán)利
在Java代碼中,需要考慮synchronized的粒度問題,否則一個(gè)線程長(zhǎng)時(shí)間占用鎖,其它爭(zhēng)搶鎖的線程會(huì)一直阻塞,直到擁有鎖的線程釋放鎖
處于BLOCKED狀態(tài)的線程,即使對(duì)其調(diào)用 thread.interrupt()也無法改變其阻塞狀態(tài),因?yàn)閕nterrupt()方法只是設(shè)置線程的中斷狀態(tài),即做一個(gè)標(biāo)記,不能喚醒處于阻塞狀態(tài)的線程
注意:ReentrantLock.lock()操作后進(jìn)入的是WAITING狀態(tài),其內(nèi)部調(diào)用的是LockSupport.park()方法

4. 等待(WAITING):

進(jìn)入該狀態(tài)的線程需要等待其他線程做出一些特定動(dòng)作(通知或中斷)。
處于這種狀態(tài)的線程不會(huì)被分配CPU執(zhí)行時(shí)間,它們要等待顯示的被其它線程喚醒。這種狀態(tài)通常是指一個(gè)線程擁有對(duì)象鎖后進(jìn)入到相應(yīng)的代碼區(qū)域后,調(diào)用相應(yīng)的“鎖對(duì)象”的wait()方法操作后產(chǎn)生的一種結(jié)果。變相的實(shí)現(xiàn)還有LockSupport.park()、Thread.join()等,它們也是在等待另一個(gè)事件的發(fā)生,也就是描述了等待的意思。
以下方法會(huì)讓線程陷入無限期等待狀態(tài):
(1)沒有設(shè)置timeout參數(shù)的Object.wait()
(2)沒有設(shè)置timeout參數(shù)的Thread.join()
(3)LockSupport.park()

注意:
LockSupport.park(Object blocker) 會(huì)掛起當(dāng)前線程,參數(shù)blocker是用于設(shè)置當(dāng)前線程的“volatile Object parkBlocker 成員變量”
parkBlocker 是用于記錄線程是被誰阻塞的,可以通過LockSupport.getBlocker()獲取到阻塞的對(duì)象,用于監(jiān)控和分析線程用的。

“阻塞”與“等待”的區(qū)別:
(1)“阻塞”狀態(tài)是等待著獲取到一個(gè)排他鎖,進(jìn)入“阻塞”狀態(tài)都是被動(dòng)的,離開“阻塞”狀態(tài)是因?yàn)槠渌€程釋放了鎖,不阻塞了;
(2)“等待”狀態(tài)是在等待一段時(shí)間 或者 喚醒動(dòng)作的發(fā)生,進(jìn)入“等待”狀態(tài)是主動(dòng)的
如主動(dòng)調(diào)用Object.wait(),如無法獲取到ReentraantLock,主動(dòng)調(diào)用LockSupport.park(),如主線程主動(dòng)調(diào)用 subThread.join(),讓主線程等待子線程執(zhí)行完畢再執(zhí)行
離開“等待”狀態(tài)是因?yàn)槠渌€程發(fā)生了喚醒動(dòng)作或者到達(dá)了等待時(shí)間

5. 超時(shí)等待(TIMED_WAITING)

該狀態(tài)不同于WAITING,它可以在指定的時(shí)間后自行返回。
處于這種狀態(tài)的線程也不會(huì)被分配CPU執(zhí)行時(shí)間,不過無需等待被其它線程顯示的喚醒,在一定時(shí)間之后它們會(huì)由系統(tǒng)自動(dòng)的喚醒。

以下方法會(huì)讓線程進(jìn)入TIMED_WAITING限期等待狀態(tài):
(1)Thread.sleep()方法
(2)設(shè)置了timeout參數(shù)的Object.wait()方法
(3)設(shè)置了timeout參數(shù)的Thread.join()方法
(4)LockSupport.parkNanos()方法
(5)LockSupport.parkUntil()方法

6. 終止(TERMINATED)

表示該線程已經(jīng)執(zhí)行完畢。

二、線程組

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

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

  • Java多線程入門不完全指南 序言 最近在讀《把時(shí)間當(dāng)作朋友》,序言就教導(dǎo)我“無論是誰,都是在某一刻意識(shí)到時(shí)間的珍...
    leo5592368閱讀 3,580評(píng)論 2 5
  • 線程池ThreadPoolExecutor corepoolsize:核心池的大小,默認(rèn)情況下,在創(chuàng)建了線程池之后...
    irckwk1閱讀 864評(píng)論 0 0
  • 線程1.優(yōu)先級(jí)2.守護(hù)線程3.常用方法4.線程狀態(tài) 多線程操作1.volatile2.Atomic3.CAS 鎖[...
    Jude95閱讀 7,525評(píng)論 4 121
  • 文/靜態(tài)極妍 說一個(gè)人“學(xué)得少”,是說這個(gè)人學(xué)習(xí)時(shí)間花得少;“會(huì)得多”是指學(xué)習(xí)的效果好;綜合起來就是花最少的學(xué)習(xí)時(shí)...
    靜態(tài)極妍閱讀 609評(píng)論 0 5
  • 查看所有tag 刪除本地tag 刪除遠(yuǎn)程的tag 新建tag 把本地tag推送到遠(yuǎn)程
    張先森Mr_zhang閱讀 3,282評(píng)論 0 4

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