先上结论:run只是Thread里面的一个普通方法,start是启动线程的方法。何以见得呢?可以执行下面的代码看看run和start的区别:
packagecom.basic.thread;/***@authorzhangxingrui
* @create 2019-02-16 20:12
**/
public classTestRunAndStart {private static voidsayHello(){
System.out.println("hello, world");
}public static voidmain(String[] args) {
Thread thread= new Thread(newRunnable() {
@Overridepublic voidrun() {
sayHello();
System.out.println("Current thread: " +Thread.currentThread().getName());
}
});
thread.run();
thread.start();
}
}
执行结果:
由此可以看到子线程是由start来启动的,里面调用了run,所以打印出来的是子线程的name。
另外也可以从start方法的底层代码看到,首先进入start方法里面
public synchronized voidstart() {/*** 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 newIllegalThreadStateException();/*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看源码
这里调用了JVM_StartThread,在jvm.h里面
继续进入
重点看最下面的语句native_thread = new JavaThread(&thread_entry, sz),好,new JavaThread的时候传入了thread_entry,我们再去
看一下啊thread_entry是什么:
在thread_entry这个函数里面调用call_virtual方法,重点是它传入的参数run_method_name,从这里我们就知道了,噢,
原来start最终会在新线程里面调用run方法。