Java線程Run和Start的區別


先上結論: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方法。

 


免責聲明!

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



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