天天看點

回顧Java多線程程式設計——線程生命周期

一 概述

Java内置了對多線程程式設計的支援,使得可以通過充分利用cpu來開發出高效率的程式。一條線程是指程序中一個單一順序的控制流,一個程序可以并發使用多個線程,每條線程則并行執行各自的任務。

二 回顧程序

一個程序包括由作業系統配置設定的記憶體空間,含有一個或多個線程,一個線程必須是某個程序的一部分而無法獨立存在,而程序會一直運作,直到所有的非守護線程都與運作結束才能結束。

三 一個線程的生命周期

回顧Java多線程程式設計——線程生命周期

線程建立狀态:使用java中的new關鍵字和Thread類或者其子類執行個體化出一個線程對象後,該線程對象會處于建立狀态,并且保持這個狀态直到調用線程的start()方法

public class Thread implements Runnable { public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }
}
           

就緒狀态:當線程對象調用了start()方法之後,該線程就進入了就緒狀态,就緒狀态的線程處于就緒隊列中,要等待JVM裡線程排程器的排程。

運作狀态:如果就緒狀态的線程擷取CPU資源,就可以執行run()方法,此時線程便處于運作狀态。處于運作狀态的線程最為複雜,它可以變為阻塞狀态,就緒狀态和死亡狀态。

/* What will be run. */
    private Runnable target;
    
    //Thread重寫了Runnable中的run方法
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
           

阻塞狀态:如果一個線程執行了sleep(睡眠),suspend(挂起)等方法,釋放目前所占用的資源之後,該線程就從運作狀态進入阻塞狀态。在睡眠時間已到或者獲得裝置資源之後可以重新進入就緒狀态。

public static native void sleep(long millis) throws InterruptedException;

    public static void sleep(long millis, int nanos)
    throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }

        sleep(millis);
    }
           
//Java1.8中該方法提示棄用
    @Deprecated
    public final void suspend() {
        checkAccess();
        suspend0();
    }
           

阻塞狀态的幾種情況:

等待阻塞:運作狀态中的線程運作wait()方法時,是的該線程進入等待阻塞狀态。

[Object類中]
   public final native void wait(long timeout) throws InterruptedException;

   public final void wait(long timeout, int nanos) throws InterruptedException {
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0) {
            timeout++;
        }

        wait(timeout);
    }

    public final void wait() throws InterruptedException {
        wait(0);
    }
           

同步阻塞:線程由于同步鎖被其它線程占用在擷取synchronized同步鎖失敗。

其他阻塞:通過調用線程的 sleep() 或 join() 發出了 I/O 請求時,線程就會進入到阻塞狀态。當sleep() 狀态逾時,join() 等待線程終止或逾時,或者 I/O 處理完畢,線程重新轉入就緒狀态。

       死亡狀态:   一個運作狀态的線程完成任務或者其他終止條件發生時,該線程就切換到終止狀态。

繼續閱讀