線程的生命周期:(新建、就緒、運行、阻塞、死亡)
新建狀態(tài):使用new關鍵字創(chuàng)建一個線程對象后既處于新建狀態(tài),由虛擬機為其分配內(nèi)存,并初始化其成員變量的值,線程執(zhí)行體未執(zhí)行
就緒狀態(tài):線程對象調(diào)用start()方法后處于就緒狀態(tài),由虛擬機為其創(chuàng)建方法調(diào)用棧和程序計數(shù)器,等待JVM里的調(diào)度器決定其何時開始運行
運行狀態(tài):若處于就緒狀態(tài)的線程獲得CPU,則開始執(zhí)行run()方法的線程執(zhí)行體,處于運行狀態(tài),直到系統(tǒng)分配的時間段用完則中斷,運行其他線程
阻塞狀態(tài):對于搶占式,當失去處理器資源時則進入阻塞狀態(tài),或者由線程調(diào)用sleep()方法主動進入阻塞狀態(tài),被阻塞的線程解除阻塞后,重新進入就緒狀態(tài)
死亡狀態(tài):線程的run()或call()執(zhí)行完成,則線程結束,或線程拋出異常,或直接調(diào)用stop()方法結束線程(不推薦)
控制線程
-
join:
Thread類提供的join()方法
一個線程調(diào)用另一個線程的join()方法執(zhí)行另一個線程,直到該線程執(zhí)行完才繼續(xù)執(zhí)行自己
-
后臺線程:
在后臺運行,為其他線程服務,稱為“后臺線程”、“守護線程”,如JVM的垃圾回收線程
若所有前臺線程死亡,則后臺線程自動死亡
調(diào)用Thread對象的setDaemon(true)方法可將指定線程設置為后臺線程(在調(diào)用start()前設置)
-
線程睡眠:sleep
調(diào)用Thread對象的sleep(毫秒)使線程進入阻塞(掛起)狀態(tài),在sleep過程中即使有資源也不會執(zhí)行,直到sleep時間結束
-
線程讓步:yield
yield()與sleep()相似,但yield()是使線程進入就緒狀態(tài),因此有資源時便會執(zhí)行
-
線程優(yōu)先級:
線程默認的優(yōu)先級與創(chuàng)建它的父線程相同,默認情況下,main線程具有普通優(yōu)先級
Thread類的setPriority(),getPriority()方法可設置與獲得指定線程優(yōu)先級,setPriority的參數(shù)為整數(shù)1-10
線程同步:多線程操作同一數(shù)據(jù)時容易出現(xiàn)線程不安全的問題
-
同步代碼塊
將會被多個線程訪問的對象放進obj的位置,則當某個線程訪問該對象時會先將其鎖定,同一時刻其他線程無法修改此對象,保證了線程安全
public void run() { synchronized(obj)//obj稱為同步監(jiān)視器 { ...//此處代碼就是同步代碼塊 } }
-
同步方法
使用synchronized修飾實例方法,無須顯式指定同步監(jiān)視器,同步方法的同步監(jiān)視器是this,也就是調(diào)用該方法的對象
public class Account { public synchronized void draw(double drawAmount) { ...//此同步方法的監(jiān)視器為this,即Account對象 //線程調(diào)用Acconut對象的draw方法時,將Account對象加鎖 } }
釋放同步監(jiān)視器的鎖定