首頁 > 軟體

Java並行程式設計之執行緒狀態介紹

2022-04-18 16:00:17

執行緒狀態概述

執行緒由生到死的完整過程:

當執行緒被建立並啟動以後,它既不是一啟動就進入了執行狀態,也不是一直處於執行狀態。線上程的生命週期中,有幾種狀態呢?在API中java.lang.Thread.State這個列舉中給出了六種執行緒狀態:

執行緒狀態導致狀態發生條件
NEW(新建)執行緒剛被建立,但是並未啟動。還沒呼叫start方法。MyThread t = new MyThread只有執行緒物件,沒有執行緒特徵。
Runnable(可執行)執行緒可以在java虛擬機器器中執行的狀態,可能正在執行自己程式碼,也可能沒有,這取決於作業系統處理器。呼叫了t.start()方法 :就緒(經典教法)
Blocked(鎖阻塞)當一個執行緒試圖獲取一個物件鎖,而該物件鎖被其他的執行緒持有,則該執行緒進入Blocked狀態;當該執行緒持有鎖時,該執行緒將變成Runnable狀態。
Waiting(無限等待)一個執行緒在等待另一個執行緒執行一個(喚醒)動作時,該執行緒進入Waiting狀態。進入這個狀態後是不能自動喚醒的,必須等待另一個執行緒呼叫notify或者notifyAll方法才能夠喚醒。
Timed Waiting(計時等待)同waiting狀態,有幾個方法有超時引數,呼叫他們將進入Timed Waiting狀態。這一狀態將一直保持到超時期滿或者接收到喚醒通知。帶有超時引數的常用方法有Thread.sleep 、Object.wait。
Teminated(被終止)因為run方法正常退出而死亡,或者因為沒有捕獲的異常終止了run方法而死亡。

睡眠sleep方法

狀態中有一個狀態叫做計時等待,可以通過Thread類的方法來進行演示。 public static void sleep(long time) 讓當前執行緒進入到睡眠狀態,到毫秒後自動醒來繼續執行

//主執行緒執行到sleep方法會休眠1秒後再繼續執行
public class Test{
  public static void main(String[] args){
    for(int i = 1;i<=5;i++){
      	Thread.sleep(1000);
        System.out.println(i)   
    } 
  }
}

等待和喚醒

public void wait() : 讓當前執行緒進入到等待狀態 此方法必須鎖物件呼叫。

public class Demo1_wait {
    public static void main(String[] args) throws InterruptedException {
	   // 步驟1 : 子執行緒開啟,進入無限等待狀態, 沒有被喚醒,無法繼續執行.
        new Thread(() -> {
            try {

                System.out.println("begin wait ....");
                synchronized ("") {
                    "".wait();
                }
                System.out.println("over");
            } catch (Exception e) {
            }
        }).start();
    }

public void notify() : 喚醒當前鎖物件上等待狀態的執行緒 此方法必須鎖物件呼叫。

public class Demo2_notify {
    public static void main(String[] args) throws InterruptedException {
	   // 步驟1 : 子執行緒開啟,進入無限等待狀態, 沒有被喚醒,無法繼續執行.
        new Thread(() -> {
            try {

                System.out.println("begin wait ....");
                synchronized ("") {
                    "".wait();
                }
                System.out.println("over");
            } catch (Exception e) {
            }
        }).start();

        //步驟2:  加入如下程式碼後, 3秒後,會執行notify方法, 喚醒wait中執行緒.
        Thread.sleep(3000);
        new Thread(() -> {
            try {
                synchronized ("") {
                    System.out.println("喚醒");
                    "".notify();
                }
            } catch (Exception e) {
            }
        }).start();
    }
}

等待喚醒的一個小例子

定義一個集合,包子鋪執行緒完成生產包子,包子新增到集合中;吃貨執行緒完成購買包子,包子從集合中移除。

  • 當包子沒有時(包子狀態為false),吃貨執行緒等待.
  • 包子鋪執行緒生產包子(即包子狀態為true),並通知吃貨執行緒(解除吃貨的等待狀態)
public class BaoZiPu extends Thread{
    private List<String> list ;
    public BaoZiPu(String name,ArrayList<String> list){
        super(name);
        this.list = list;
    }
    @Override
    public void run() {
        	int i = 0; 
            while(true){
                    //list作為鎖物件
                    synchronized (list){
                        if(list.size()>0){
                            //存元素的執行緒進入到等待狀態
                            try {
                                list.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }

                        //如果執行緒沒進入到等待狀態 說明集合中沒有元素
                        //向集合中新增元素
                        list.add("包子"+i++);
                        System.out.println(list);
                        //集合中已經有元素了 喚醒獲取元素的執行緒
                        list.notify();
                    }
                }
            }
    }
}
public class ChiHuo extends Thread {

    private List<String> list ;
    public ChiHuo(String name,ArrayList<String> list){
        super(name);
        this.list = list;
    }

    @Override
    public void run() {
 			//為了能看到效果 寫個死迴圈
                while(true){
                    //由於使用的同一個集合 list作為鎖物件
                    synchronized (list){
                        //如果集合中沒有元素 獲取元素的執行緒進入到等待狀態
                        if(list.size()==0){
                            try {
                                list.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        //如果集合中有元素 則獲取元素的執行緒獲取元素(刪除)
                        list.remove(0);
                        //列印集合 集合中沒有元素了
                        System.out.println(list);
                        //集合中已經沒有元素 則喚醒新增元素的執行緒 向集合中新增元素
                        list.notify();
                    }
                }
            }
    }
}
public class Demo {
    public static void main(String[] args) {
        //等待喚醒案例
        List&lt;String&gt; list = new ArrayList&lt;&gt;();
        // 建立執行緒物件        
         BaoZiPu bzp = new BaoZiPu("包子鋪",list);
        ChiHuo ch = new ChiHuo("吃貨",list);
        // 開啟執行緒
        bzp.start();
        ch.start();
    }
}

到此這篇關於Java並行程式設計之執行緒狀態介紹的文章就介紹到這了,更多相關Java 執行緒狀態內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com