1. 程式人生 > 程式設計 >Java多執行緒start()方法原理解析

Java多執行緒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異常。

測試程式碼:

start不可以使用多次

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

4、注意點:

start方法是被synchronized修飾的方法,可以保證執行緒安全。

由jvm建立的main方法執行緒和system組執行緒,並不會通過start來啟動。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。