这里我们能看到 start 方法中调用了 native 方法 start0来启动线程,这个方法是在 Thread 类中的静态代码块中注册的 , 这里直接调用了一个 native 方法 registerNatives
/* Make sure registerNatives is the first thing <clinit> does. */ private static native void registerNatives(); static { registerNatives(); }
由于 registerNatives 方法是本地方法,我们要看其实现源码则必须去下载 jdk 源码,关于 jdk 及虚拟机 hotspot 的源码下载可以去 openJDK 官网下载 ,参考:
我们可以本地查看源码或者直接去 查看 Thread 类对应的本地方法 .c 文件,
如上图,我们本地下载 jdk 工程,找到 src->share->native->java->lang->Thread.c 文件
上面是 Thread.c 中所有代码,我们可以看到调用了 RegisterNatives 同时可以看到 method 集合中的映射,在调用本地方法 start0 时,实际调用了 JVM_StartThread ,它自身是由 c/c++ 实现的,这里需要在 虚拟机源码中去查看,我们使用的都是 hostpot 虚拟机,这个可以去 openJDK 官网下载,上述介绍了不再多说
我们看到 JVM_StartThread 的定义是在 jvm.h 源码中,而 jvm.h 的实现则在虚拟机 hotspot 中,我们打开 hotspot 源码,找到 src -> share -> vm -> prims ->jvm.cpp 文件,在 2955 行,可以直接检索 JVM_StartThread , 方法代码如下:
JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)) JVMWrapper("JVM_StartThread"); JavaThread *native_thread = NULL; bool throw_illegal_thread_state = false; { MutexLocker mu(Threads_lock); if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) { throw_illegal_thread_state = true; } else { // We could also check the stillborn flag to see if this thread was already stopped, but // for historical reasons we let the thread detect that itself when it starts running // <1> :获取当前进程中线程的数量 jlong size = java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread)); size_t sz = size > 0 ? (size_t) size : 0; // <2> :真正调用创建线程的方法 native_thread = new JavaThread(&thread_entry, sz); if (native_thread->osthread() != NULL) { // Note: the current thread is not being used within "prepare". native_thread->prepare(jthread); } } } if (throw_illegal_thread_state) { THROW(vmSymbols::java_lang_IllegalThreadStateException()); } assert(native_thread != NULL, "Starting null thread?"); if (native_thread->osthread() == NULL) { // No one should hold a reference to the 'native_thread'. delete native_thread; if (JvmtiExport::should_post_resource_exhausted()) { JvmtiExport::post_resource_exhausted( JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS, "unable to create new native thread"); } THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "unable to create new native thread"); } // <3> 启动线程 Thread::start(native_thread); JVM_ENDJVM_ENTRY 是用来定义 JVM_StartThread 函数的,在这个函数里面创建了一个真正和平台有关的本地线程, 上述标记 <2> 处
为了进一步线程创建,我们在进入 new JavaThread(&thread_entry, sz) 中查看一下具体实现过程,在 thread.cpp 文件 1566 行处定义了 new 的方法
对于上述代码我们可以看到最终调用了 os::create_thread(this, thr_type, stack_sz); 来实现线程的创建,对于这个方法不同平台有不同的实现,这里不再赘述,
上面都是创建过程,之后再调用 Thread::start(native_thread); 在 JVM_StartThread 中调用,该方法的实现在 Thread.cpp 中