• <nav id="wkkge"><strong id="wkkge"></strong></nav>
  • <menu id="wkkge"></menu>
  • 首頁 > hot資訊 > 淺談線程的6種狀態

    淺談線程的6種狀態

    更新時間:2020-11-06 17:48 瀏覽154次 來源:動力節點

    在正式學習Java多線程這一重點內容之前,我們先來了解一下線程有哪些狀態,深入理解線程的6種狀態將會有助于后面對Thread類中的方法的理解。


    一般情況下,線程分為以下6個狀態:

    1.創建(new)狀態: 準備好了一個多線程的對象

    2.就緒(runnable)狀態: 調用了start()方法, 等待CPU進行調度

    3.運行(running)狀態: 執行run()方法

    4.阻塞(blocked)狀態: 線程為等待某個對象的“鎖”而暫時放棄cpu的使用權,且不再參與CPU使用權競爭。直到條件滿足時,重新回到就緒狀態,重新參與競爭CPU。

    5.等待(waiting):線程無限等待某個對象的“鎖”,或等待另一個線程結束的狀態到來。

    6.終止(dead)狀態: 線程銷毀


    當需要新起一個線程來執行某個子任務時,就創建了一個線程。但是線程創建之后,不會立即進入就緒狀態,因為線程的運行需要一些條件(比如內存資源,程序計數器、Java棧、本地方法棧都是線程私有的,所以需要為線程分配一定的內存空間),只有線程運行需要的所有條件滿足了,才進入就緒狀態。

    當線程進入就緒狀態后,不代表立刻就能獲取CPU執行時間,也許此時CPU正在執行其他的事情,因此它要等待。當得到CPU執行時間之后,線程便真正進入運行狀態。


    線程在運行狀態過程中,可能有多個原因導致當前線程不繼續運行下去,比如用戶主動讓線程睡眠(睡眠一定的時間之后再重新執行)、用戶主動讓線程等待,或者被同步塊給阻塞,此時就對應著多個狀態:time waiting(睡眠或等待一定的事件)、waiting(等待被喚醒)、blocked(阻塞)。

    當由于突然中斷或者子任務執行完畢,線程就會被消亡。

    下面這副圖描述了線程從創建到消亡之間的狀態:

    image.png


    在有些教程上將blocked、waiting、time waiting統稱為阻塞狀態,這個也是可以的,只不過這里我們需要將線程的狀態和Java中的方法調用聯系起來,所以將waiting和time waiting兩個狀態分離出來。

    注:sleep和wait的區別:

    sleep是Thread類的方法,wait是Object類中定義的方法.

    Thread.sleep不會導致鎖行為的改變, 如果當前線程是擁有鎖的, 那么Thread.sleep不會讓線程釋放鎖.

    Thread.sleep和Object.wait都會暫停當前的線程. OS會將執行時間分配給其它線程. 區別是, 調用wait后, 需要別的線程執行notify/notifyAll才能夠重新獲得CPU執行時間。


    下面通過示例演示sleep()是不會釋放鎖的。

    SleepLockTest.java的源碼

    public class SleepLockTest{

    private static Object obj = new Object();

    public static void main(String[] args){

    ThreadA t1 = new ThreadA("t1");

    ThreadA t2 = new ThreadA("t2");

    t1.start();

    t2.start();

    }

    static class ThreadA extends Thread{

    public ThreadA(String name){

    super(name);

    }

    public void run(){

    // 獲取obj對象的同步鎖

    synchronized (obj) {

    try {

    for(int i=0; i <10; i++){

    System.out.printf("%s: %d\n", this.getName(), i);

    // i能被4整除時,休眠100毫秒

    if (i%4 == 0)

    Thread.sleep(100);

    }

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    }

    }


    主線程main中啟動了兩個線程t1和t2。t1和t2在run()會引用同一個對象的同步鎖,即synchronized(obj)。在t1運行過程中,雖然它會調用Thread.sleep(100);但是,t2是不會獲取cpu執行權的。因為,t1并沒有釋放“obj所持有的同步鎖”!若我們注釋掉synchronized (obj)后再次執行該程序,t1和t2是可以相互切換的。


    以上就是關于線程狀態的內容講解,也是本站的多線程教程中的開篇內容,想要系統地學習多線程,弄懂線程之間的狀態轉換是必不可少的學習內容,有利于我們理解多線程中的各種Thread類的方法和多線程編程。


    相關文章推薦
    HOT資訊 >

    熱門課程推薦

    全部班型支持免費試學

    動力節點在線報名表(此信息已加密,請放心填寫)

    返回頂部
  • <nav id="wkkge"><strong id="wkkge"></strong></nav>
  • <menu id="wkkge"></menu>
  • 面对面棋牌游戏