JAVA | 線程(二)線程的生命週期

生命週期

  1. 新建(New)
  2. 就緒(Runnable)
  3. 運行(Running)
  4. 阻塞(Blocked)
  5. 死亡(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)阻塞:
當發生以下情況時,會進入阻塞狀態:

  1. 線程調用了Sleep方法主動放棄所佔用的處理器資源
  2. 線程調用了一個阻塞式IO方法,在該方法返回前,該線程被阻塞
  3. 線程視圖獲得一個同步監視器,但是該監視器正在被佔用
  4. 線程等待某一個通知(notify)
  5. 線程調用了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();
                    }
                }
            }
        });
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章