生命週期
- 新建(New)
- 就緒(Runnable)
- 運行(Running)
- 阻塞(Blocked)
- 死亡(Dead)
說明
當CPU運行多個線程的時候,線程狀態就會在運行和阻塞直接來回切換
一、 新建(New)和就緒(Runnable):
class FirstThread extends Thread{
private int i;
@Override
public void run() {
super.run();
for (;i < 5; i++){
Log.e("testthread",getName() +","+ i);
}
}
}
mBntFun1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
for (int i = 0;i < 100;i++){
Log.e("testthread",Thread.currentThread().getName() +","+ i);
if (i == 20){
// 直接調用run()
new FirstThread().run();
// 直接調用run()
new FirstThread().run();
}
}
}
});
說明
(1)通過new 創建線程之後,該線程處於新建狀態,此時只是爲這個線程分配了內存,初始化了成員變量的值;
(2)當調用start()之後,線程處於就緒狀態,虛擬機會爲它創建方法調用棧和程序計數器,此時並沒有開始運行線程,什麼時候運行,取決於線程調度器的調度。
(3)當直接調用線程的run(),此時就只是一個普通的方法,而不是線程執行體了。
(4)直接調用run(),在Thread子類中通過 getName()得到的就是當前的對象的名字,而不是線程名
(5)調用了run()之後,線程不再處於新建狀態了,不要再次調用start(),否則會拋出IllegalThreadStateException異常
二、運行(Running)和阻塞(Blocked)狀態
(1)運行
處於就緒狀態的線程得到CPU後,開始執行run()方法,則該線程處於運行狀態
(2)阻塞:
當發生以下情況時,會進入阻塞狀態:
- 線程調用了Sleep方法主動放棄所佔用的處理器資源
- 線程調用了一個阻塞式IO方法,在該方法返回前,該線程被阻塞
- 線程視圖獲得一個同步監視器,但是該監視器正在被佔用
- 線程等待某一個通知(notify)
- 線程調用了suspend()方法將線程掛起,該方法容易導致死鎖,所以應該儘量避免使用該方法
(3)就緒
當發生以下情況時,會從阻塞進入就緒狀態
1.調用sleep方法經過了指定的時間
2.線程調用阻塞式IO方法已經返回
3.線程成功獲得了試圖取得的同步監視器
4.線程正在等待某一個通知時,其他線程發出了通知
5.處於掛起狀態的線程被調用了resume方法
三、線程死亡
線程會以以下三種方式結束,結束後就處於死亡狀態
- run或call方法執行完成,線程正常結束
- 線程拋出一個未捕獲的Exception或Error
- 直接調用線程的stop()方法來結束該線程,該方法很容易導致死鎖,不推薦使用
說明
- 當主線程結束時,其他的線程不受任何影響,並不會隨之結束,一旦子線程起來後,它就擁有和主線程同樣的地位,不會受主線程的影響了。
- 爲了判斷某個線程是否已經死亡,可以調用線程的isAlive(),處於就緒、運行、阻塞時,就返回true;處於新建、死亡兩種狀態時,就返回false
- 不要對一個已經死亡的線程調用start()使它重新啓動,死亡就是死亡,該線程將不可再次作爲線程執行---->死了不能再復生
class FirstThread extends Thread{
private int i;
@Override
public void run() {
super.run();
for (;i < 100; i++){
Log.e("testthread",getName() +","+ i);
}
}
}
mBntFun1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FirstThread thread = new FirstThread();
for (int i = 0;i < 300;i++){
Log.e("testthread",Thread.currentThread().getName() +","+ i);
if (i == 20){
// 創建並啓動線程
thread.start();
Log.e("testthread",thread.isAlive()+"");
}
if (i>20 && !thread.isAlive()){
// 試圖再次啓動該線程,後面程序會崩潰
thread.start();
}
}
}
});