天天看點

java多線程(二)線程狀态與操作線程的常用方法

文章目錄

      • 一 . 線程的基本狀态
      • 二 . 線程狀态圖
      • 三 . 在Java代碼中的線程狀态
      • 四 . 操作線程的常用方法
      • 五 . 常用方法的使用

一 . 線程的基本狀态

  • 新生狀态:線程開啟
  • 就緒狀态:具有了除CPU以外的所有資源
  • 運作狀态:CPU排程,開始真正執行
  • 阻塞狀态:因為某些原因放棄CPU,等待再次排程
  • 死亡狀态:正常結束或者被強制結束

二 . 線程狀态圖

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-Ba7hBo7d-1586010838194)(線程狀态圖.png)]

  • 死亡的線程不會回到就緒狀态,而是從新生狀态開始
  • 阻塞狀态的程序回到就緒狀态後,進入就緒隊列,與其他在就緒隊列中的線程共同等待CPU排程

三 . 在Java代碼中的線程狀态

  • 新生:線程對象一旦建立就進入了新生狀态
  • 就緒:當調用start()方法時線程立刻進入就緒狀态(并不意味着立即執行)
  • 運作:當CPU排程時代碼真正運作才進入運作狀态
  • 阻塞:當調用sleep(),wait()等方法或同步鎖固定式,線程進入阻塞狀态,就是代碼不再往下執行
  • 死亡:代碼執行完畢或者中斷執行

四 . 操作線程的常用方法

  • sleep()
    • 使線程停止一段時間,将線程處于阻塞狀态(如果隻有一個線程,那麼調用sleep()方法之後,需要等待sleep(time)中的time時間結束後才能進入就緒隊列)
  • join()
    • 阻塞指定線程等到另一個線程完成以後再繼續執行
  • yield()
    • 暫停目前正在執行的線程
    • 注意:不是阻塞程序,而是直接将程序變為就緒狀态
  • setDaemon()
    • 将指定的線程設定成背景線程(即守護者線程)
    • 建立使用者線程結束時,背景線程也會随之結束
    • 隻能線上程啟動之前把他設為背景線程
  • setPriority(int newPriority);getPriority()
    • 設定線程的優先級(這裡的優先級代表機率,并不是優先級高的線程先執行,而是優先級越高,線程執行可能性越大)
    • 範圍從0到10,預設為5
  • stop()和distory()(已經不推薦使用)
    • 停止線程

五 . 常用方法的使用

傳回值類型 方法和描述
static void sleep(long millis) 使目前正在執行的線程以指定的毫秒數暫停(暫時停止執行),具體取決于系統定時器和排程程式的精度和準确性。
static void sleep(long millis, int nanos) 導緻正在執行的線程以指定的毫秒數加上指定的納秒數來暫停(臨時停止執行),這取決于系統定時器和排程器的精度和準确性。
static void yield() 對排程程式的一個暗示,即目前線程願意産生目前使用的處理器。
void setPriority(int newPriority) 更改此線程的優先級。
void setDaemon(boolean on) 将此線程标記為 daemon線程或使用者線程。
void join() 等待這個線程死亡。
void stop() 已棄用 這種方法本質上是不安全的。 使用Thread.stop停止線程可以解鎖所有已鎖定的螢幕(由于未ThreadDeath ThreadDeath異常在堆棧中ThreadDeath的自然結果)。
void destroy() 已棄用 這種方法最初是為了銷毀這個線程而沒有任何清理。 它所持有的任何螢幕都将保持鎖定。
public class test {
    public static void main(String[] args) throws InterruptedException {
        //sleep()方法是使目前線程阻塞的時間
        Thread.sleep(6*1000);
        //等待6秒後才會繼續執行下面的代碼
        //暫停目前的主程序,由于目前隻有一個程序,是以暫停完畢後會繼續往下執行
        Thread.yield();
        Thread you = new Thread(new You());
        Thread God = new Thread(new God());
        //設定you這個線程的優先級,優先級越高被調用的可能性越大,優先級隻能在[1-10]之間,預設的優先級是5
        you.setPriority(10);
        you.start();
        //調用jion()方法.表示必須等待you這個線程執行完畢才能繼續執行
        you.join();
        //設定God為守護程序,JVM不會等待守護程序結束,JVM等待所有使用者程序結束後就會停止
        //是以這裡God線程内部雖然是個while(true)循環,但因為它是個守護程序,是以等到主線程和you這個線程結束後,JVM就會停止運作
        God.setDaemon(true);
        God.start();
    }
}
class God extends Thread{
    public void run(){
        while(true) {
            System.out.println("上帝守護你");
        }
    }
}
class You extends Thread{
    public void run (){
        System.out.println("吃喝玩樂");
    }
}
           
吃喝玩樂
上帝守護你
上帝守護你
上帝守護你
上帝守護你
上帝守護你
上帝守護你
Process finished with exit code 0
           
  • 這裡再說明一下守護線程,程序分為使用者程序和守護線程,JVM運作時會等待所有使用者線程運作完成才會結束終止。而不會管守護線程有沒有運作完成。
  • 是以雖然God這個線程内部執行的部分是個死循環,但等到使用者線程運作完畢後,JVM會停止,是以有那樣的運作結果。
  • 還有一點我們現在已經抛棄stop()和distroy()方法,那麼怎麼去人為操作使得線程停止,這裡API給的意見是加一個變量去控制,比如上邊的God線程中while循環的參數換成一個變量,在我們想要停時隻需要把變量置為false。