Thread中start和run方法的区别
由打印结果可以知道,当执行
start()
方法时,会创建一个新的线程
Thread-0
public class ThreadTest {
private static void attack(){
System.out.println("fight");
System.out.println("current thread: "+Thread.currentThread().getName());
}
public static void main(String[] args) {
Thread t = new Thread(){
@Override
public void run(){
attack();
}
};
System.out.println("current main thread: "+Thread.currentThread().getName());
// t.run();
t.start();
}
}
打印结果
current main thread: main
fight
current thread: Thread-0
如果
t.start();
换成
t.run();
,可以看出
run()
方法没有创建新的线程,仍然是
main
线程
current main thread: main
fight
current thread: main
查看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
其中重要的是
start0()
方法,进入查看源码。
发现是native方法,通过下方链接可查看源码
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e36dcb7d407e/src/share/native/java/lang/Thread.c
Thread.c源码
#include "jni.h"
#include "jvm.h"
#include "java_lang_Thread.h"
#define THD "Ljava/lang/Thread;"
#define OBJ "Ljava/lang/Object;"
#define STE "Ljava/lang/StackTraceElement;"
#define STR "Ljava/lang/String;"
#define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
static JNINativeMethod methods[] = {
{"start0", "()V", (void *)&JVM_StartThread},
{"stop0", "(" OBJ ")V", (void *)&JVM_StopThread},
{"isAlive", "()Z", (void *)&JVM_IsThreadAlive},
{"suspend0", "()V", (void *)&JVM_SuspendThread},
{"resume0", "()V", (void *)&JVM_ResumeThread},
{"setPriority0", "(I)V", (void *)&JVM_SetThreadPriority},
{"yield", "()V", (void *)&JVM_Yield},
{"sleep", "(J)V", (void *)&JVM_Sleep},
{"currentThread", "()" THD, (void *)&JVM_CurrentThread},
{"countStackFrames", "()I", (void *)&JVM_CountStackFrames},
{"interrupt0", "()V", (void *)&JVM_Interrupt},
{"isInterrupted", "(Z)Z", (void *)&JVM_IsInterrupted},
{"holdsLock", "(" OBJ ")Z", (void *)&JVM_HoldsLock},
{"getThreads", "()[" THD, (void *)&JVM_GetAllThreads},
{"dumpThreads", "([" THD ")[[" STE, (void *)&JVM_DumpThreads},
{"setNativeName", "(" STR ")V", (void *)&JVM_SetNativeThreadName},
};
#undef THD
#undef OBJ
#undef STE
#undef STR
JNIEXPORT void JNICALL
Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
}
可以看到
{"start0", "()V", (void *)&JVM_StartThread},
,即
start0
使用
jvm.h
中的JVM_StartThread方法,我们去查看
jvm.h
的代码。通过下方链接可查看
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/cf6e3496e19a/src/share/vm/prims/jvm.cpp
顺着方法往下看
可以看到new了一个JavaThread,其中传递了两个参数
thread_entry
和
sz
可以看到,JavaThread会执行
run
方法