iT邦幫忙

2021 iThome 鐵人賽

DAY 21
0
自我挑戰組

Java SE系列 第 21

Day21:人生跑馬燈

  • 分享至 

  • xImage
  •  

在我們稍稍脫離初學程式的階段時,可能會開始使用許多框架工具,抑或是寫WebApp時使用Servlet API,都會發現去了解架構是很重要的事情,了解架構才有辦法讓我們開發軟體的時候知道自己在哪裡,其中有一部分是去了解軟體的生命週期。

我覺得這是滿有趣的一件事,軟體這種純粹人工的事物理應沒有生命,但在我們人類的理解上,生命週期是最恰當的詞語來形容了。

今天就要來談談執行緒(Thread)的生命週期(Life Cycle)。

我個人在初學Java時,學到執行緒真的是滿頭痛的,不是很能在腦海中有明確的畫面去想像,不過在了解到執行緒的生命週期後,讓我有豁然開朗的感覺。

來上圖!
ThreadLifeCycle
當我們實作Runnable介面或繼承Thread類別,覆寫run()方法後,就要創建Thread實例來啟動該執行緒:

Thread thread01 = new Thread(() -> {
    for(int i = 0; i < 10; i++){
        System.out.println(i);
    }
});
thread01.start();

當呼叫了Thread的start()後,就是開始了執行緒的生命週期了,thread會進到Runnable的狀態,這個階段就像是被放進一個等待區一樣,而電腦的CPU就像是工作人員會來叫號,被叫到的thread就可以離開等待區,進到工作區占用電腦CPU資源開始跑run()方法;要注意這邊的叫號是隨機的,或者可以透過Java API提供的setPriority()方法設定執行緒被叫號的優先權。

當執行緒的run()方法內容執行完畢後,thread就會進入Terminated的狀態,相當於這個執行緒的生命到了盡頭,就算在thread.start()一遍也沒辦法再跑一次,甚至還會吐出IllegalThreadStateException例外。

除了Runnable以及Running的階段外,有些情況執行緒會進到類似隔離區的Blocked狀態,通常是當執行緒在跑輸入輸出的程式時就會進到Blocked狀態,等輸入輸出完成後才會重新回到等待區Runnable等待CPU叫號;也可能是我們主動在某個流程中呼叫執行緒的sleep()方法,就會強制該執行緒進到Blocked狀態;也可能是在設定了synchronized的程式中等待物件內部鎖(intrinsic lock),也會進到Blocked狀態。

以上是執行緒生命週期的整體概念,下面接著要來說說程式碼上執行緒的執行狀況。

public static void Main(String[] args){
    Thread thread01 = new Thread(() -> {
        for(int i = 0; i < 10; i++){
            System.out.println("thread01 " + i);
        }
    });
    Thread thread02 = new Thread(() -> {
        for(int i = 0; i < 10; i++){
            System.out.println("thread02 " + i);
        }
    });
    
    thread01.setDaemon(true);
    
    thread02.start(); 
    thread01.start();
}

我們初學常常測試程式碼使用的Main方法,其實本身就是一個thread,稱為main thread;當Main方法執行完時,main thread也就Terminated了,JVM隨之關閉。

而當我們在Main方法中去啟動其他執行緒時,我們的main thread會等到這些執行緒都執行完畢後,才會進到Terminated狀態;不過有一種設定叫做Daemon,如上面的程式碼範例,我們設定了thread01.setDaemon(true),被設定為Daemon的執行緒不會被main thread等待,main thread跑完了就會直接進到Terminated狀態,所以上面的程式碼跑完會發現thread01有時候會跑不到9,但是thread02一定會跑到9。


上一篇
Day20:銀河帝國
下一篇
Day22:歐印萬
系列文
Java SE30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言