關於多線程start()方法原理解讀


1、為什么啟動線程不用run()方法而是使用start()方法

run()方法只是一個類中的普通方法,調用run方法跟調用普通方法一樣

而start()是創建線程等一系列工作,然后自己調用run里面的任務內容。

驗證代碼:

/**
 * @data 2019/11/8 - 下午10:29
 * 描述:run()和start()
 */
public class StartAndRunMethod {
    public static void main(String[] args) { Runnable runnable = new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()); } }; runnable.run(); new Thread(runnable).start(); } }

結果:

main
Thread-0


2、start()源碼解讀

  • 啟動新線程檢查線程狀態
  •     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();

    關於threadStatus源碼:

  •     /*
         * Java thread status for tools, default indicates thread 'not yet started'
         */
        private volatile int threadStatus;

    通過代碼可以看到就是threadStatus就是記錄Thread的狀態,初始線程默認為0.

  • 加入線程組
  •  /* 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);
  • 調用start0()
  • 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 */
                }
            }
        }

    start0()方法使用c++編寫的方法,這些代碼在gdk代碼中,所以這里不再這里探究了。


 

3、start()方法不能使用多次

通過剛剛源碼分析,就知道start方法剛開始就檢查線程狀態,當線程創建后或結束了,該狀態就不同於初始化狀態就會拋出

IllegalThreadStateException異常。

測試代碼:

/**
 * @data 2019/11/8 - 下午11:57
 * 描述:start不可以使用多次
 */
public class CantStartTwice {
    public static void main(String[] args) {
        Thread thread = new Thread();
        thread.start();
        thread.start();
    }
}
start不可以使用多次

 
        

 4、注意點:

start方法是被synchronized修飾的方法,可以保證線程安全。

由jvm創建的main方法線程和system組線程,並不會通過start來啟動。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM