日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

java threadstatus_Thread之一:线程生命周期及六种状态

發(fā)布時(shí)間:2024/1/23 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java threadstatus_Thread之一:线程生命周期及六种状态 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、線程的生命周期及五種基本狀態(tài)

關(guān)于Java中線程的生命周期,首先看一下下面這張較為經(jīng)典的圖:

上圖中基本上囊括了Java中多線程各重要知識(shí)點(diǎn)。掌握了上圖中的各知識(shí)點(diǎn),Java中的多線程也就基本上掌握了。主要包括:

Java線程具有七種基本狀態(tài)

新建狀態(tài)(New):至今尚未啟動(dòng)的線程的狀態(tài)。線程剛被創(chuàng)建,但尚未啟動(dòng)。如:Thread t = new MyThread();

就緒狀態(tài)(Runnable):當(dāng)調(diào)用線程對(duì)象的start()方法(t.start();),線程即進(jìn)入就緒狀態(tài)。處于就緒狀態(tài)的線程,只是說(shuō)明此線程已經(jīng)做好了準(zhǔn)備,隨時(shí)等待CPU調(diào)度執(zhí)行,并不是說(shuō)執(zhí)行了t.start()此線程立即就會(huì)執(zhí)行;

運(yùn)行狀態(tài)(Running):當(dāng)CPU開(kāi)始調(diào)度處于就緒狀態(tài)的線程時(shí),此時(shí)線程才得以真正執(zhí)行,即進(jìn)入到運(yùn)行狀態(tài)。注:就 ? ? 緒狀態(tài)是進(jìn)入到運(yùn)行狀態(tài)的唯一入口,也就是說(shuō),線程要想進(jìn)入運(yùn)行狀態(tài)執(zhí)行,首先必須處于就緒狀態(tài)中;

無(wú)限期等待(Waiting):位于對(duì)象等待池中的阻塞狀態(tài)(Blocked in object’s wait pool):當(dāng)線程處于運(yùn)行狀態(tài)時(shí),如果執(zhí)行了某個(gè)對(duì)象的wait()方法,Java虛擬機(jī)就會(huì)把線程放到這個(gè)對(duì)象的等待池中,這涉及到“線程通信”的內(nèi)容。處于這種狀態(tài)的線程不會(huì)被分配處理器執(zhí)行時(shí)間,它們要等待被其他線程顯示喚醒。以下方法會(huì)讓線程陷入無(wú)限期的等待狀態(tài):

沒(méi)有設(shè)置timeout參數(shù)的Object::wait()方法

沒(méi)有設(shè)置timeout參數(shù)的Thread::join()方法

LockSupport::park()方法

限期等待(Timed Waiting):處于這種狀態(tài)的線程也不會(huì)被分配處理器執(zhí)行時(shí)間,不過(guò)無(wú)須等待其他線程顯示喚醒,在一定時(shí)間后它們由系統(tǒng)自動(dòng)喚醒。以下方法會(huì)讓線程進(jìn)入期限等待狀態(tài):

Thread::sleep()方法

設(shè)置了timeout參數(shù)的Object::wait()方法

設(shè)置了timeout參數(shù)的Thread::join()方法

LockSupport::parkNanos()方法

LockSupport::parkUntil()方法

阻塞狀態(tài)(Blocked):處于運(yùn)行狀態(tài)中的線程由于某種(當(dāng)線程處于運(yùn)行狀態(tài)時(shí),試圖獲得某個(gè)對(duì)象的同步鎖時(shí),如果該對(duì)象的同步鎖已經(jīng)被其他線程占用,Java虛擬機(jī)就會(huì)把這個(gè)線程放到這個(gè)對(duì)象的鎖池中,這涉及到“線程同步”的內(nèi)容?!揪€程在獲取synchronized同步鎖失敗(因?yàn)殒i被其它線程所占用)】)原因,暫時(shí)放棄對(duì)CPU的使用權(quán),停止執(zhí)行,此時(shí)進(jìn)入阻塞狀態(tài),直到其進(jìn)入到就緒狀態(tài),才有機(jī)會(huì)再次被CPU調(diào)用以進(jìn)入到運(yùn)行狀態(tài)。

“阻塞狀態(tài)”與“等待狀態(tài)”的區(qū)別:“阻塞狀態(tài)”在等待著獲取一個(gè)排它鎖,這個(gè)事件將在另一個(gè)線程放棄這個(gè)鎖的時(shí)候發(fā)生;而“等待狀態(tài)”則是在等待一段時(shí)間,或者喚醒動(dòng)作發(fā)生。在程序進(jìn)入同步區(qū)域的時(shí)候,線程就會(huì)進(jìn)入阻塞狀態(tài)。

死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法,該線程結(jié)束生命周期。

JVM線程運(yùn)行狀態(tài) (JVM Thread Status)

至今尚未啟動(dòng)的線程的狀態(tài)。線程剛被創(chuàng)建,但尚未啟動(dòng)。

可運(yùn)行線程的線程狀態(tài)。線程正在JVM中執(zhí)行,有可能在等待操作系統(tǒng)中的其他資源,比如處理器。

受阻塞并且正在等待監(jiān)視器的某一線程的線程狀態(tài)。處于受阻塞狀態(tài)的某一線程正在等待監(jiān)視器鎖,以便進(jìn)入一個(gè)同步的塊/方法,或者在調(diào)用 Object.wait 之后再次進(jìn)入同步的塊/方法。在Thread Dump日志中通常顯示為?java.lang.Thread.State: BLOCKED (on object monitor)?。

某一等待線程的線程狀態(tài)。線程正在無(wú)期限地等待另一個(gè)線程來(lái)執(zhí)行某一個(gè)特定的操作,線程因?yàn)檎{(diào)用下面的方法之一而處于等待狀態(tài):

不帶超時(shí)的 Object.wait 方法,日志中顯示為?java.lang.Thread.State: WAITING (on object monitor)

不帶超時(shí)的 Thread.join 方法

LockSupport.park 方法,日志中顯示為?java.lang.Thread.State: WAITING (parking)

指定了等待時(shí)間的某一等待線程的線程狀態(tài)。線程正在等待另一個(gè)線程來(lái)執(zhí)行某一個(gè)特定的操作,并設(shè)定了指定等待的時(shí)間,線程因?yàn)檎{(diào)用下面的方法之一而處于定時(shí)等待狀態(tài):

Thread.sleep 方法

指定超時(shí)值的 Object.wait 方法

指定超時(shí)值的 Thread.join 方法

LockSupport.parkNanos

LockSupport.parkUntil

線程處于終止?fàn)顟B(tài)。

根據(jù)Java Doc中的說(shuō)明,在給定的時(shí)間上,一個(gè)只能處于上述的一種狀態(tài)之中,并且這些狀態(tài)都是JVM的狀態(tài),跟操作系統(tǒng)中的線程狀態(tài)無(wú)關(guān)。

JAVA虛擬機(jī)啟動(dòng)程序步驟:

(1) Main是啟動(dòng)時(shí)候的主線程,即程序入口

(2) 在main函數(shù)結(jié)束后,虛擬機(jī)會(huì)自動(dòng)啟動(dòng)一個(gè)DestroyJavaVM線程,該線程會(huì)等待所有user thread 線程結(jié)束后退出(即,只剩下daemon 線程和DestroyJavaVM線程自己,整個(gè)虛擬機(jī)就退出,此時(shí)daemon線程被終止),因此,如果不希望程序退出,只要?jiǎng)?chuàng)建一個(gè)非daemon的子線程,讓線程不停的sleep即可。

線程的創(chuàng)建

Thread類,有一個(gè)start方法,即啟動(dòng)該線程。 啟動(dòng)的線程會(huì)執(zhí)行該類的run方法。注意:因?yàn)閱?dòng)線程時(shí)要執(zhí)行某個(gè)過(guò)程,因此,通常是需要重新實(shí)現(xiàn)run方法的

線程的結(jié)束

run模塊執(zhí)行完成主動(dòng)退出,或者被其他線程強(qiáng)行終止。

通過(guò)jstack pid >1.txt

線程狀態(tài)樣例

等待狀態(tài)樣例

上面例子中,IoWaitThread 線程保持等待狀態(tài)并從 LinkedBlockingQueue 接收消息,如果 LinkedBlockingQueue 一直沒(méi)有消息,該線程的狀態(tài)將不會(huì)改變。

阻塞狀態(tài)樣例

在上面的例子中,BLOCKED_TEST pool-1-thread-1 線程占用了 <0x0000000780a000b0> 鎖,然而 BLOCKED_TEST pool-1-thread-2 和 BLOCKED_TEST pool-1-thread-3 threads 正在等待獲取鎖。

死鎖狀態(tài)樣例

上面的例子中,當(dāng)線程 A 需要獲取線程 B 的鎖來(lái)繼續(xù)它的任務(wù),然而線程 B 也需要獲取線程 A 的鎖來(lái)繼續(xù)它的任務(wù)的時(shí)候發(fā)生的。在 thread dump 中,你能看到 DEADLOCK_TEST-1 線程持有 0x00000007d58f5e48 鎖,并且嘗試獲取 0x00000007d58f5e60 鎖。你也能看到 DEADLOCK_TEST-2 線程持有 0x00000007d58f5e60,并且嘗試獲取 0x00000007d58f5e78,同時(shí) DEADLOCK_TEST-3 線程持有 0x00000007d58f5e78,并且在嘗試獲取 0x00000007d58f5e48 鎖,如你所見(jiàn),每個(gè)線程都在等待獲取另外一個(gè)線程的鎖,這狀態(tài)將不會(huì)被改變直到一個(gè)線程丟棄了它的鎖。

無(wú)限等待的Runnable狀態(tài)樣例

上例中線程的狀態(tài)是RUNNABLE,但在下面的堆棧日志中發(fā)現(xiàn)socketReadThread 線程正在無(wú)限等待讀取 socket,因此不能單純通過(guò)線程的狀態(tài)來(lái)確定線程是否處于阻塞狀態(tài),應(yīng)該根據(jù)詳細(xì)的堆棧信息進(jìn)行分析。

總結(jié)

以上是生活随笔為你收集整理的java threadstatus_Thread之一:线程生命周期及六种状态的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。