• 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方法。

     

    书上说,天下没有不散的宴席。不要怕,书上还说了,人生何处不相逢。

  • 相关阅读:
    SpringCloud学习----阳哥(十一)
    SpringCloud学习----阳哥(十)
    SpringCloud学习----阳哥(九)
    SpringCloud学习----阳哥(八)
    SpringCloud学习----阳哥(七)
    SpringCloud学习----阳哥(六)
    Linux系统管理(软件安装篇)
    每次都能遇到的莫名其妙问题,谨记,速查手册
    Mysql 常用表达式
    精选博客收集
  • 原文地址:https://www.cnblogs.com/alinainai/p/10389161.html
Copyright © 2020-2023  润新知