我們都知道 new Thread().start() 能啟動線程,但 run() 方法究竟是如何被調用執行的?本文將從操作系統線程模型切入,層層剖析 Java 線程與本地線程的映射關係,深入 JDK 源碼追蹤 start() 到 run() 的完整調用鏈路。
run() 本質是一個回調函數,與普通方法無異;start() 則負責啟動本地線程並安排 run() 執行。
// Thread.java
private native void start0();
// 類加載時靜態塊註冊本地方法
static {
registerNatives();
}
private static native void registerNatives();
registerNatives() 在 Thread.c 中實現,將 start0 映射到 JVM_StartThread:
// Thread.c
static JNINativeMethod methods[] = {
{"start0", "()V", (void *)&JVM_StartThread},
{"stop0", "(" OBJ ")V", (void *)&JVM_StopThread},
// ... 其他本地方法
};
// jvm.cpp
JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)) {
// 創建平台相關的本地線程
JavaThread* native_thread = new JavaThread(&thread_entry, sz);
// ...
}
線程入口函數 thread_entry 通過 JNI 調用 Java 線程的 run():
static void thread_entry(JavaThread* thread, TRAPS) {
HandleMark hm(THREAD);
Handle obj(THREAD, thread->threadObj());
JavaValue result(T_VOID);
// 關鍵:調用 run 方法
JavaCalls::call_virtual(&result, obj,
KlassHandle(THREAD, SystemDictionary::Thread_klass()),
vmSymbolHandles::run_method_name(), // "run"
vmSymbolHandles::void_method_signature(),
THREAD);
}
方法名在 vmSymbols.hpp 定義:
template(run_method_name, "run")
總結:Java 線程啟動本質是創建本地線程,由 JVM 通過 JNI 回調執行 Java 層的 run() 方法。理解這一機制,有助於深入掌握線程生命周期、上下文切換及性能調優的底層邏輯。