多线程——线程的生命周期
生活随笔
收集整理的這篇文章主要介紹了
多线程——线程的生命周期
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
線程狀態(tài):
與人有生老病死一樣,線程也同樣要經(jīng)歷新建、就緒、運(yùn)行(活動)、阻塞和死亡五種不同的狀態(tài)。這五種狀態(tài)
都可以通過Thread類中的方法進(jìn)行控制。創(chuàng)建并運(yùn)行線程:
① 新建狀態(tài)(New Thread):在Java語言中使用new 操作符創(chuàng)建一個線程后,該線程僅僅是一個空對象,
它具備類線程的一些特征,但此時系統(tǒng)沒有為其分配資源,這時的線程處于創(chuàng)建狀態(tài)。
線程處于創(chuàng)建狀態(tài)時,可通過Thread類的方法來設(shè)置各種屬性,如線程的優(yōu)先級(setPriority)、
線程名(setName)和線程的類型(setDaemon)等。② 就緒狀態(tài)(Runnable):使用start()方法啟動一個線程后,系統(tǒng)為該線程分配了除CPU外的所需資源,
使該線程處于就緒狀態(tài)。此外,如果某個線程執(zhí)行了yield()方法,那么該線程會被暫時剝奪CPU資源,
重新進(jìn)入就緒狀態(tài)。③ 運(yùn)行狀態(tài)(Running):Java運(yùn)行系統(tǒng)通過調(diào)度選中一個處于就緒狀態(tài)的線程,使其占有CPU并轉(zhuǎn)為運(yùn)行狀態(tài)。
此時,系統(tǒng)真正執(zhí)行線程的run()方法。④ 阻塞和喚醒線程
阻塞狀態(tài)(Blocked):一個正在運(yùn)行的線程因某些原因不能繼續(xù)運(yùn)行時,就進(jìn)入阻塞狀態(tài)。這些原因包括:a)當(dāng)執(zhí)行了某個線程對象的sleep()等阻塞類型的方法時,該線程對象會被置入一個阻塞集內(nèi),等待超時而自動蘇醒。b) 當(dāng)多個線程試圖進(jìn)入某個同步區(qū)域時,沒能進(jìn)入該同步區(qū)域的線程會被置入鎖定集,直到獲得該同步區(qū)域的鎖,進(jìn)入就緒狀態(tài)。c)當(dāng)線程執(zhí)行了某個對象的wait()方法時,線程會被置入該對象的等待集中,直到執(zhí)行了該對象的notify()方法wait()/notify()方法的執(zhí)行要求線程首先獲得該對象的鎖。⑤ 死亡狀態(tài)(Dead):線程在run()方法執(zhí)行結(jié)束后進(jìn)入死亡狀態(tài)。此外,如果線程執(zhí)行了interrupt()
或stop()方法,那么它也會以異常退出的方式進(jìn)入死亡狀態(tài)。終止線程的三種方法
① 使用退出標(biāo)志,使線程正常退出,也就是當(dāng)run方法完成后線程終止,推薦使用。
② 使用stop方法強(qiáng)制終止線程(這個方法不推薦使用,因?yàn)閟top和suppend、resume一樣,也可能
發(fā)生不可預(yù)料的結(jié)果)。
③ 使用interrupt方法中斷線程。
java多線程回顧2:生命周期與控制
1、 線程生命周期概述 線程的生命周期如下圖: 2、 新建與就緒當(dāng)程序使用new關(guān)鍵字創(chuàng)建一個線程之后,線程就處于新建狀態(tài)了。此時線程只是被分配了內(nèi)存資源, 初始化了成員變量。當(dāng)線程對象被調(diào)用了start()方法之后,該線程就處于就緒狀態(tài)了。表示這個線程可以運(yùn)行但還沒有運(yùn)行, 至于線程何時開始運(yùn)行,取決于jvm的線程調(diào)度器。有一點(diǎn)值得注意,啟動線程應(yīng)該使用start()方法,而不是run()方法。如果使用run()方法,程序會把 run()方法當(dāng)成一個普通方法立刻執(zhí)行,而不會啟動新線程。此外,也不可以對已就緒的線程再次調(diào)用start()方法,會引發(fā)異常。3、 阻塞與運(yùn)行 當(dāng)就緒的線程獲得CPU資源開始執(zhí)行方法體,該線程就變成運(yùn)行狀態(tài)。當(dāng)線程在運(yùn)行的過程中被中斷,則線程變?yōu)樽枞麪顟B(tài)。被阻塞的線程在合適的時候會重新進(jìn)入就緒狀態(tài), 然后再次獲取CPU資源,進(jìn)入運(yùn)行狀態(tài)。以下情況將使線程進(jìn)入阻塞狀態(tài): 線程調(diào)用sleep方法,主動放棄所占CPU資源。 線程掉用了一個阻塞式IO方法,在方法返回前,線程被阻塞。 線程試圖獲取一個同步鎖,但是該鎖被其他線程占有。 線程在等待通知(線程同步notify) 線程調(diào)用suspend方法掛起。該方法容易死鎖,少用。以下情況將解除阻塞狀態(tài),使線程重新進(jìn)入就緒狀態(tài): sleep方法計(jì)時結(jié)束 阻塞式IO方法已經(jīng)返回 獲取了同步鎖 等到了其他線程發(fā)出的通知 調(diào)用resume方法解除了掛起狀態(tài)此外,調(diào)用yield方法可以使運(yùn)行狀態(tài)的線程直接轉(zhuǎn)入就緒狀態(tài)。4、 線程死亡 以下三種情況時線程將死亡。 run()方法執(zhí)行結(jié)束,線程結(jié)束。 線程拋出了一個未捕獲的Exception或Error 調(diào)用了線程的stop()方法。該方法容易死鎖,少用。5、線程控制 舉個例子,線程A在執(zhí)行中調(diào)用線程B的join方法,線程A將被阻塞,直到線程B執(zhí)行完為止。線程代碼如下: //通過實(shí)現(xiàn)Runnable接口創(chuàng)建線程類public class ThreadTwo implements Runnable{private int i;//run方法同樣是線程的執(zhí)行體@Overridepublic void run() {for (i = 0; i < 5; i++) {//實(shí)現(xiàn)Runnable接口創(chuàng)建線程類時,只能使用Thread.currentThread()來獲取當(dāng)前線程System.out.println(Thread.currentThread().getName()+" "+i);}}}public class TestThreadJoin {public static void main(String[] args) throws InterruptedException {ThreadTwo st = new ThreadTwo();new Thread(st,"打醬油的線程").start();for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName()+" "+i);if (i==2) {ThreadTwo st2 = new ThreadTwo();Thread thread = new Thread(st2,"被join的線程");thread.start();//main線程調(diào)用了thread線程的join方法,必須等thread執(zhí)行結(jié)束才會向下執(zhí)行thread.join();}}}}main 0打醬油的線程 0main 1打醬油的線程 1main 2打醬油的線程 2打醬油的線程 3被join的線程 0打醬油的線程 4被join的線程 1被join的線程 2被join的線程 3被join的線程 4main 3main 4main 5main 6main線程的i等于2時,啟動了“被join的線程”,這時main線程進(jìn)入阻塞狀態(tài),只有“打醬油的線程”“ 被join的線程”在運(yùn)行,等“被join的線程”運(yùn)行完了,main線程才重新開始運(yùn)行。5.2后臺線程 后臺線程也稱“守護(hù)線程”或“精靈線程”。jvm的垃圾回收線程就是典型的后臺進(jìn)程。一般線程在被創(chuàng)建之后,其生命周期是獨(dú)立的。而后臺進(jìn)程的生命周期與前臺進(jìn)程相關(guān):當(dāng)所有前臺進(jìn)程都 死亡,后臺進(jìn)程也隨之死亡。使用thread.setDaemon(true)可將線程設(shè)為后臺線程,且必須在線程啟動前設(shè)置。前臺線程創(chuàng)建的線程默認(rèn)為前臺線程。后臺線程創(chuàng)建的線程默認(rèn)為后臺線程。5.3線程睡眠sleep Sleep方法是Thread類提供的一個靜態(tài)方法,讓當(dāng)前線程進(jìn)入阻塞狀態(tài),時間到了之后,線程會自動轉(zhuǎn)入 就緒狀態(tài)。5.4線程讓步y(tǒng)ield yield方法和sleep方法類似,也是一個Thread類提供的靜態(tài)方法,和sleep不同的是,yield是讓線程轉(zhuǎn)入 就緒狀態(tài)。 當(dāng)某個線程調(diào)用了yield方法后,和當(dāng)前線程優(yōu)先級一樣,或更高的線程會轉(zhuǎn)入運(yùn)行狀態(tài)。5.5線程優(yōu)先級 Thread類提供了setPriority(int newPriority)方法和getPriority()方法來設(shè)置和獲取線程優(yōu)先級, 優(yōu)先級的范圍通常在1-10之間,10是最高優(yōu)先級。 不過不同系統(tǒng)的優(yōu)先級數(shù)值可能不同,所以通常推薦使用Thread類的三個靜態(tài)常量來設(shè)置優(yōu)先級, 分別是MAX_PRIORITY、MIN_PRIORITY、NORM_PRIORITY。?
總結(jié)
以上是生活随笔為你收集整理的多线程——线程的生命周期的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA多线程和并发
- 下一篇: final、finally与finali