1. 程式人生 > >Java線程Run和Start的區別

Java線程Run和Start的區別

dsta for 調用 bubuko bool oid art not in package

先上結論:run只是Thread裏面的一個普通方法,start是啟動線程的方法。何以見得呢?可以執行下面的代碼看看run和start的區別:

package com.basic.thread;

/**
 * @author zhangxingrui
 * @create 2019-02-16 20:12
 **/
public class TestRunAndStart {

    private static void sayHello(){
        System.out.println("hello, world");
    }

    public static
void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public void run() { sayHello(); System.out.println("Current thread: " + Thread.currentThread().getName()); } }); thread.run(); thread.start(); } }

  執行結果:

技術分享圖片

  由此可以看到子線程是由start來啟動的,裏面調用了run,所以打印出來的是子線程的name。

  另外也可以從start方法的底層代碼看到,首先進入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(); /* 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 */ } } }

  裏面調用了start0,繼續跟進

private native void start0();

  哦,這裏就調了native方法了,再往下我們就看不到了。但是可以去openjdk的源碼裏面去看一下,我用的是jdk8。

  去openjdk看源碼

  https://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/f0b93fbd8cf8/src/share/native/java/lang/Thread.c

  技術分享圖片

  這裏調用了JVM_StartThread,在jvm.h裏面

  繼續進入

  https://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/76a9c9cf14f1/src/share/vm/prims/jvm.cpp

  技術分享圖片

  重點看最下面的語句native_thread = new JavaThread(&thread_entry, sz),好,new JavaThread的時候傳入了thread_entry,我們再去

看一下啊thread_entry是什麽:

  技術分享圖片

  在thread_entry這個函數裏面調用call_virtual方法,重點是它傳入的參數run_method_name,從這裏我們就知道了,噢,

原來start最終會在新線程裏面調用run方法。

 

Java線程Run和Start的區別