Java併發編程之線程狀態與創建線程的方式

在Java併發編程中,線程所處的狀態以及創建線程的方式算是’開學第一課’了。而從本文開始,我將對Java併發做一個系統的認識。話不多說,開始進入主題。

一:線程狀態

在Thread類中詳細的枚舉了線程的狀態,如下:

   public enum State {
        /**
         * 創建了線程還未調用srart()方法的時候,線程處於NEW的狀態
         */
        NEW,

        /**
         * 線程處於可運行的狀態,在此狀態下,如果操作系統分配了相應的時間片
         * 則線程將開始真正的運行
         */
        RUNNABLE,

        /**
         * 線程處於阻塞狀態,在此狀態下將等待着直到獲得監視器鎖。
         * 以下情況將進入阻塞狀態
         * 一:進入同步被synchronized修飾的同步代碼塊,方法或者鎖的重入
         */
        BLOCKED,

        /**
         * 線程出於等待的狀態,以下的方法將會使線程出於此狀態:
         * 一:調用了object.wait()方法
         * 二:調用了thread.join()方法
         * 三:調用了LockSupport()方法
         * 處於於此狀態的線程將等待着另一個線程執行特定的操作,比如調用了wait()方法
         * 將等待着另一個線程調用notify()或者notifyAll 的方法喚醒。
         */
        WAITING,

        /**
         * 超時等待的狀態.以下操作將進入超時等待的狀態:
         * 一:Thread.sleep()方法的調用
         * 二:object.wait(long) 加入超時時間的wait方法
         * 三:thread.join(long millis) 
         * 四:LockSupport.parkNanos() 或者LockSupport..parkUntil()
         */
        TIMED_WAITING,

        /**
         * 終止狀態的線程
         * 線程完成了所有的操作處於此狀態
         */
        TERMINATED;
    }

以上的枚舉我們可以清楚的看到線程有NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED 6種狀態,線程總是處於6種狀態的某一種。我們將通過一個圖更加清楚的看看各個狀態之間是怎麼變更的:
在這裏插入圖片描述
上圖需要說明的是,在線程的枚舉狀態中,其實並沒有RUNING的狀態,RUNNABLE與RUNNING的狀態的區別是是否獲得了由操作系統分配的時間片,這裏爲了流程更加的清晰易懂,做了區分的處理。 以下,將從代碼的角度分析下線程的狀態:

public class ThreadState implements Runnable{
    @Override
    public void run() {
        //RUNNABLE
        System.out.println("線程的狀態爲:"+Thread.currentThread().getState());
    }

    public static void main(String[] args) {
        Thread thread =new Thread(new ThreadState());
        //NEW
        System.out.println("線程的狀態爲:"+thread.getState());
        thread.start();
    }
}

才創建線程,線程處於NEW狀態,調用start方法後,獲得時間片後,執行run方法,線程處於RUNNABLE狀態。


public class ThreadState implements Runnable{
    @Override
    public void run() {
        synchronized (ThreadState.class){
            while (true){
                System.out.println("線程的狀態爲:"+Thread.currentThread().getState());
            }
        }
    }

    public static void main(String[] args) {
        ThreadState threadState = new ThreadState();
        Thread thread1 =new Thread(threadState);
        Thread thread2 =new Thread(threadState);
        thread1.start();
        thread2.start();
    }
}

查看線程的狀態,
在這裏插入圖片描述
可以看到先獲得時間片的線程處於RUNNABLE的狀態,而另外一個線程則處於BLOCK的狀態。


public class ThreadState implements Runnable{
    @Override
    public void run() {
        synchronized (this){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        ThreadState threadState = new ThreadState();
        Thread thread1 =new Thread(threadState);
        thread1.start();
    }
}

在這裏插入圖片描述
當調用wait方法的時候,當前線程會處於WAITING狀態


public class ThreadState implements Runnable{
    @Override
    public void run() {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ThreadState threadState = new ThreadState();
        Thread thread1 =new Thread(threadState);
        thread1.start();
    }
}

在這裏插入圖片描述
當調用了sleep方法的時候,則線程處於TIMED_WAITING超時等待狀態。


二:創建線程的方式

這裏主要是對其進行一個總結:
1:實現Runnable接口或匿名內部類的方式
2:繼承Thread類
3:線程池的實現
4:帶返回值的線程創建方式(Callable與FutureTask)
5:Spring對異步的支持(@Async)
6:Lamada表達式中的並行計算

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章