java多線程學習3-線程狀態轉換

來源:互聯網
上載者:User

 

線程的5個狀態可分為,分別是新、死、可運行、運行、阻塞狀態。可以用如下一幅圖表示:

 

1、  初生狀態:已建立線程對象,但沒有執行start()方法的線程;

2、  可運行狀態:已執行start()方法,並滿足運行條件,等待CPU調度;

3、  運行狀態:正在CPU上運行;

4、  死亡狀態:線程運行結束,也就是run()方法運行結束;

5、  阻塞狀態:正在啟動並執行線程因為某些原因,如CPU調度策略,或者有更高優先順序的進程要運行,或者啟動並執行條件不滿足等,暫停執行。

下面介紹通過睡眠和等待來控制線程。

1、  睡眠

可以線上程的run()方法中調用Thread.sleep(long millis)和Thread.sleep(long millis, int nanos)靜態方法強制當前正在執行的線程休眠(暫停執行),

 

class Demo3 extends Thread{

    @Override

    public void run() {

       for(int i = 5;i<11;i++){

           System.out.println("這裡線程睡眠5秒鐘");

           try {

              Thread.sleep(2000);

           } catch (InterruptedException e) {

              // TODO Auto-generated catch block

              e.printStackTrace();

           }

       }

       System.out.println("線程運行結束");

    }

}

這樣執行的結果就是每隔兩秒鐘列印一句。

注意:

a、線程睡眠是協助所有線程獲得運行機會的最好方法。

b、線程睡眠到期自動蘇醒,並返回到可運行狀態,不是運行狀態。sleep()中指定的時間是線程不會啟動並執行最短時間。因此,sleep()方法不能保證該線程睡眠到期後就開始執行。

c、sleep()是靜態方法,只能控制當前正在啟動並執行線程。

 

2、線程讓步yield()

要理解yield(),必須瞭解線程的優先順序的概念。線程總是存在優先順序,優先順序範圍在1~10之間。JVM線程發送器是基於優先順序的搶先調度機制。在大多數情況下,當前啟動並執行線程優先順序將大於或等於線程池中任何線程的優先順序。但這僅僅是大多數情況。

 

注意:當設計多線程應用程式的時候,一定不要依賴於線程的優先順序。因為線程調度優先順序操作是沒有保障的,只能把線程優先順序作用作為一種提高程式效率的方法,但是要保證程式不依賴這種操作。

 

當線程池中線程都具有相同的優先順序,發送器的JVM實現自由選擇它喜歡的線程。這時候發送器的操作有兩種可能:一是選擇一個線程運行,直到它阻塞或者運行完成為止。二是時間分區,為池內的每個線程提供均等的運行機會。

 

設定線程的優先順序:線程預設的優先順序是建立它的執行線程的優先順序。可以通過setPriority(int newPriority)更改線程的優先順序。例如:

        Thread t = new MyThread();
        t.setPriority(8);
        t.start();

線程優先順序為1~10之間的正整數,JVM從不會改變一個線程的優先順序。然而,1~10之間的值是沒有保證的。一些JVM可能不能識別10個不同的值,而將這些優先順序進行每兩個或多個合并,變成少於10個的優先順序,則兩個或多個優先順序的線程可能被映射為一個優先順序。

 

線程預設優先順序是5,Thread類中有三個常量,定義線程優先順序範圍:

static int MAX_PRIORITY
          線程可以具有的最高優先順序。
static int MIN_PRIORITY
          線程可以具有的最低優先順序。
static int NORM_PRIORITY
          分配給線程的預設優先順序。

  

Thread.yield()方法作用是:暫停當前正在執行的線程對象,並執行其他線程。

yield()應該做的是讓當前運行線程回到可運行狀態,以允許具有相同優先順序的其他線程獲得運行機會。因此,使用yield()的目的是讓相同優先順序的線程之間能適當的輪轉執行。但是,實際中無法保證yield()達到讓步目的,因為讓步的線程還有可能被線程發送器再次選中。

結論:yield()從未導致線程轉到等待/睡眠/阻塞狀態。在大多數情況下,yield()將導致線程從運行狀態轉到可運行狀態,但有可能沒有效果。

 

3、join()方法

 

Thread的非靜態方法join()讓一個線程B“加入”到另外一個線程A的尾部。在A執行完畢之前,B不能工作。例如:

        Thread t = new MyThread();
        t.start();
        t.join();

另外,join()方法還有帶逾時限制的重載版本。 例如t.join(5000);則讓線程等待5000毫秒,如果超過這個時間,則停止等待,變為可運行狀態。

 

package learn.thread;

 

public class LearnThree {

 

    public static void main(String[] args) {

       Demo3 demo = new Demo3();

      

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

           System.out.println(Thread.currentThread().getName()+"這是中main線程中。");

           if (5 == i) {

              demo.start();

              try {

 

                  demo.join();

              } catch (InterruptedException e) {

                  // TODO Auto-generated catch block

                  e.printStackTrace();

              }

           }

 

       }

    }

}

 

class Demo3 extends Thread {

 

    @Override

    public void run() {

       for (int i = 5; i < 11; i++) {

           System.out.println("這裡線程睡眠5秒鐘");

           //            Thread.sleep(2000);

           Thread.yield();

       }

       System.out.println("線程運行結束");

    }

}

 參考:http://lavasoft.blog.51cto.com/62575/99153

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.