Java 线程调用start()后会立即执行run()方法吗?

Java 线程调用start()后会立即执行run()方法吗?_第1张图片
别想当然

问题

Java 线程调用start()后会立即执行run()方法吗?

我们在开发中,经常和线程打交道,有些东西总是司空见惯,想当然地认为某些事情理所当然...
但是今天偶然发现一个有趣的现象:

class Test {
    public static void main(String[] args) {
        System.out.println("hello https://tool.lu/");

        Runnable runnable = new Runnable(){
            @Override
                public void run() {
                System.out.println("--run()--");
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();
        System.out.println("--after start()--");
    }
}


运行结果如下:


运行结果

看到运行结果之后,我愣了一下,WTF?
跟我想的有点不一样啊,

理论上来讲,线程调用start()之后,将会调用该线程的run();
我又赶紧去查看了Java的官方文档:JavaAPI

Thread的start()

Cause this thread to begin execution ; the Java Virtual Machine calls the run method of this thread.

通过上面我们可以发现start()就是使该线程开始运行,JVM会调用线程的run()方法。

那我们只能从源码中找答案啦。

  /**
     * Causes this thread to begin execution; the Java Virtual Machine
     * calls the run method of this thread.
     * 

* The result is that two threads are running concurrently: the * current thread (which returns from the call to the * start method) and the other thread (which executes its * run method). *

* It is never legal to start a thread more than once. * In particular, a thread may not be restarted once it has completed * execution. * * @exception IllegalThreadStateException if the thread was already * started. * @see #run() * @see #stop() */ 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". */ // Android-changed: throw if 'started' is true if (threadStatus != 0 || started) 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); started = false; try { nativeCreate(this, stackSize, daemon); 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 */ } } } private native static void nativeCreate(Thread t, long stackSize, boolean daemon);

关键代码已经贴出,但是似乎关键在于nativeCreate()方法。该方法属于c方法,有时间再追踪一下。

思考

通过代码测试我们发现线程调用start()方法,并不会立刻执行run()方法。但是两者之间的时间差是多少呢?

测试用例,有兴趣的朋友can have a try.

把运行结果给出来:


Java 线程调用start()后会立即执行run()方法吗?_第2张图片
运行结果

通过我的多次测试,run()和start()的时间差一般都在[0,8]之内,当然运行足够多次会发现时间差会更大。

总结

虽然该用例看似没什么卵用,但不亲自上手尝试,还真会回答错...有趣有趣...
需要注意的是如果我们在线程中创建对象,而在start()方法后直接使用该对象,就会出现该问题测试用例。


夫小惑易方,大惑易性...

你可能感兴趣的:(Java 线程调用start()后会立即执行run()方法吗?)