線程與進程
線程:進程中負責程序執(zhí)行的執(zhí)行單元,線程本身依靠程序進行運行,線程是程序中的順序控制流,只能使用分配給程序的資源和環(huán)境笆载。
進程:執(zhí)行中的程序,一個進程至少包含一個線程。
可以將一個正在運行的.exe程序理解為一個進程
線程是進程中獨立運行的子任務(wù)凉驻,比如QQ.exe有視屏線程腻要、下載文件線程、傳輸數(shù)據(jù)線程等在后臺默默的運行涝登。線程允許在一個進程中存在多個程序控制流雄家,線程會共享進程范圍的資源,例如內(nèi)存句柄和文件句柄胀滚,但每個線程都有各自的計數(shù)器趟济、棧和局部變量等。線程可以看做一個基本的調(diào)度單位咽笼,如果沒有明確的協(xié)同機制顷编,那么線程將彼此獨立運行。當一個線程訪在使用一個變量剑刑,而另一個線程在同時訪問這個變量時將造成不可預(yù)料的后果媳纬。
多線程的優(yōu)點:充分使用cpu資源
如果任務(wù)一等待遠程服務(wù)器返回數(shù)據(jù),那么cpu就會一直處于等待狀態(tài)任務(wù)二必須等任務(wù)一運行完之后才能運行施掏,CPU利用率大幅度降低钮惠。
使用多線程
繼承Thread類
創(chuàng)建好了自己的線程類之后,就可以創(chuàng)建線程對象了七芭,然后通過start()方法去啟動線程萌腿。注意,不是調(diào)用run()方法啟動線程抖苦,run方法中只是定義需要執(zhí)行的任務(wù)毁菱,如果調(diào)用run方法,即相當于在主線程中執(zhí)行run方法锌历,跟普通的方法調(diào)用沒有任何區(qū)別
實現(xiàn)Runnable接口
Runnable的中文意思是“任務(wù)”贮庞,顧名思義,通過實現(xiàn)Runnable接口究西,我們定義了一個子任務(wù)窗慎,然后將子任務(wù)交由Thread去執(zhí)行。注意卤材,這種方式必須將Runnable作為Thread類的參數(shù)遮斥,然后通過Thread的start方法來創(chuàng)建一個新線程來執(zhí)行該子任務(wù)。如果調(diào)用Runnable的run方法的話扇丛,是不會創(chuàng)建新線程的术吗,這根普通的方法調(diào)用沒有任何區(qū)別。
線程狀態(tài)
1帆精、新建狀態(tài)(New):新創(chuàng)建了一個線程對象较屿。
2隧魄、就緒狀態(tài)(Runnable):線程對象創(chuàng)建后,其他線程調(diào)用了該對象的start()方法隘蝎。該狀態(tài)的線程位于可運行線程池中购啄,變得可運行,等待獲取CPU的使用權(quán)嘱么。
3狮含、運行狀態(tài)(Running):就緒狀態(tài)的線程獲取了CPU,執(zhí)行程序代碼曼振。
4几迄、阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因為某種原因放棄CPU使用權(quán),暫時停止運行拴测。直到線程進入就緒狀態(tài)乓旗,才有機會轉(zhuǎn)到運行狀態(tài)。阻塞的情況分三種:
(一)集索、等待阻塞:運行的線程執(zhí)行wait()方法屿愚,JVM會把該線程放入等待池中。
(二)务荆、同步阻塞:運行的線程在獲取對象的同步鎖時妆距,若該同步鎖被別的線程占用,則JVM會把該線程放入鎖池中函匕。
(三)娱据、其他阻塞:運行的線程執(zhí)行sleep()或join()方法,或者發(fā)出了I/O請求時盅惜,JVM會把該線程置為阻塞狀態(tài)中剩。當sleep()狀態(tài)超時、join()等待線程終止或者超時抒寂、或者I/O處理完畢時结啼,線程重新轉(zhuǎn)入就緒狀態(tài)。
5屈芜、死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法郊愧,該線程結(jié)束生命周期。
常用方法
1井佑、currentThread()返回當前代碼段正在被哪個線程調(diào)用
2属铁、isAlive()判斷當前線程是否處于活動狀態(tài)
3、sleep()方法在指定的毫秒數(shù)內(nèi)讓當前“正在執(zhí)行的線程”休眠(暫停執(zhí)行)
4躬翁、getId()獲取線程的唯一標識
5焦蘑、yield()放棄當前的cpu資源,讓給其他的任務(wù)占用cpu執(zhí)行
停止線程
java中有三種方法可以終止正在運行的線程:
- 使用退出標志姆另,使線程正常退出喇肋,也就是當run方法完成后線程終止
- 使用stop方法強行終止線程坟乾,但不推薦迹辐,stop會釋放鎖給數(shù)據(jù)造成不一致性的結(jié)果蝶防,stop和suspend以及resume一樣,都是過期的方法明吩,使用它們可能會產(chǎn)生不可預(yù)料的結(jié)果间学,
- 使用interrupt方法中斷線程,但不會真的停止線程印荔,而是在當前線程打了一個停止的標記低葫。
判斷線程是否中止:
this.interrupted:測試當前狀態(tài)是否是中斷狀態(tài),執(zhí)行后具有將狀態(tài)標志清除為false的功能仍律。
this.isInterrupted測試線程Thread對象是否已經(jīng)是中斷狀態(tài)嘿悬,但不清除狀態(tài)標志。
線程的優(yōu)先級
線程的優(yōu)先級分為1~10個等級水泉,線程的優(yōu)先級具有繼承性善涨,比如A線程啟動了B線程,則B線程的優(yōu)先級與A是一樣的草则。setPriority()可以用來設(shè)置線程的優(yōu)先級钢拧。優(yōu)先級具有
守護線程
java線程有兩種線程,一種是用戶線程炕横,另一種是守護線程源内。當進程轉(zhuǎn)中不存在非守護線程時,守護線程自動銷毀份殿,典型的就是GC(垃圾回收器)線程膜钓。