1. 程式人生 > 其它 >Thread多執行緒2-執行緒狀態

Thread多執行緒2-執行緒狀態

執行緒狀態

1.執行緒狀態

建立:執行緒一旦建立Thread t=new Thread();就進入新生狀態;

就緒:呼叫start()方法,執行緒立即進入就緒狀態,但不意味著立即被排程執行;

執行:被CPU排程進入執行狀態,執行緒才真正執行執行緒體的程式碼塊;

阻塞:當呼叫sleep、wait或同步鎖定時,執行緒進入阻塞狀態,程式碼不再往下執行;阻塞時間解除後,重新進入就緒狀態,等待CPU排程執行;

死亡:執行緒中斷或者結束,一旦進入死亡狀態,就不能再次啟動;

2.執行緒方法

  • void setPriority(int newPriority) //更改執行緒的優先順序
  • static void sleep(long millis) //在指定的毫秒數內讓當前正在執行的執行緒休眠
  • void join() //等待該執行緒終止
  • static void yiels() //暫定當前正在執行的執行緒物件,並執行其他執行緒
  • void interrupt() //中斷執行緒,不推薦使用
  • boolean isAlive() //測試執行緒是否處於活動狀態

3.執行緒停止

不推薦使用JDK提供的stop()、destroy()方法; //已過時棄用
推薦執行緒自己停止,利用次數,不建議死迴圈;
建議使用一個標誌位進行終止變數,當flag=false,則終止執行緒執行;

/**
 * 停止執行緒
 */
public class ThreadStop implements Runnable{
    //1.設定一個標誌位
    private boolean flag=true;

    @Override
    public void run() {
        int i=0;
        while (flag){
            System.out.println("run...Thread"+i++);
        }
    }
    //2.設定一個公開的方法停止執行緒,轉換標誌位
    public void stop(){
        this.flag=false;
    }

    public static void main(String[] args) {
        ThreadStop threadStop=new ThreadStop();
        new Thread(threadStop).start();

        for(int i=0;i<100;i++){
            System.out.println("main"+i);
            if(i==50){
                threadStop.stop();
                System.out.println("該執行緒停止了");
            }
        }
    }
}

4.執行緒休眠(sleep)

  • sleep(long millis)指定當前執行緒阻塞的毫秒數;
  • sleep存在異常InterruptedException;
  • sleep時間達到後執行緒進入就緒狀態;
  • sleep可以模擬網路延時、倒計時等;
  • 每一個物件都有一個鎖,sleep不會釋放鎖;
    【用途】除錯程式併發,延時,計數等

5.執行緒禮讓(yield)

  • 讓當前正在執行的執行緒暫停,但不阻塞;
  • 將執行緒從執行狀態轉為就緒狀態;
  • 讓CPU重新排程,禮讓不一定成功;

6.執行緒加入(join)

  • 合併執行緒,待此執行緒執行完成後,再執行其他執行緒,其他執行緒阻塞;
  • 可以想象成插隊;

7.執行緒狀態(getState)

  • NEW 尚未啟動的執行緒;
  • RUNNABLE 在java虛擬機器中執行的執行緒;
  • BLOCKED 被阻塞等待監視器鎖定的執行緒;
  • WAITING 正在等待另一個執行緒執行特定動作的執行緒;
  • TIMED_WAITING 正在等待另一個執行緒執行動作達到指定等待時間的執行緒;
  • TERMINATED 已退出的執行緒;
    一個執行緒可以在給定的時間處於一個狀態,這些狀態時不反映任何作業系統執行緒狀態的虛擬機器狀態;
/**
 * 執行緒狀態觀測
 */
public class ThreadState {
    public static void main(String[] args) {
        Thread thread=new Thread(()->{
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("執行緒結束了");
        });
        //觀測狀態
        Thread.State state=thread.getState();
        System.out.println("new: "+state); //new
        //觀測啟動後
        thread.start();
        System.out.println("start: "+thread.getState()); //run

        //持續觀測
        while (thread.getState()!=Thread.State.TERMINATED){
            try {
                Thread.sleep(1000);
                System.out.println("now: "+thread.getState());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //System.out.println("now: "+thread.getState());
        //thread.start(); //報錯,死亡後的執行緒不能再啟動
    }
}

8.執行緒優先順序

  • java提供一個執行緒排程器來監控程式中啟動後進入就緒狀態的所有執行緒,執行緒排程器按照優先順序決定應該排程哪個執行緒來執行;
  • 執行緒優先順序用數字表示,範圍從1-10
    Thread.MIN_PRIORITY=1;
    Thread.MAX_PRIORITY=10;
    Thread.NORM_PRIORITY=5;
  • 使用以下方法獲取或改變優先順序
    getPriority();
    setPriotity(int i);

優先順序的設定建議在start()之前;
優先順序低只意味著獲得排程的概率低,並不一定低,決定權在CPU;

9.守護(daemon)執行緒

  • 執行緒分為使用者執行緒和守護執行緒;
  • 虛擬機器必須確保使用者執行緒執行完畢;
  • 虛擬機器不用等待守護執行緒執行完畢;
  • 守護執行緒如:後臺記錄操作日誌、監控記憶體、垃圾回收等
  • 通過以下方法設定執行緒型別
    setDaemon(Boolean b); //false或預設表示使用者執行緒,true表示守護執行緒