原来还能这么看Java线程的状态及转换( 二 )


在Thread类实例化的同时 , 会首先调用registerNatives方法 , 注册本地Native方法,动态绑定JVM方法
private static native void registerNatives();static {registerNatives();}在Thread类中通过registerNatives将指定的本地方法绑定到指定函数 , 比如start0本地方法绑定到JVM_StartThread函数:
...static JNINativeMethod methods[] = {{"start0","()V",(void *)&JVM_StartThread},{"stop0","(" OBJ ")V", (void *)&JVM_StopThread},{"isAlive","()Z",(void *)&JVM_IsThreadAlive},...源码见:
http://hg.openjdk.java.NET/jdk8u/jdk8u60/jdk/file/935758609767/src/share/native/java/lang/Thread.c
JVM_StartThread是JVM层函数,抛去各种情况的处理 , 主要是通过new JavaThread(&thread_entry, sz)来创建JVM线程对象
JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))JVMWrApper("JVM_StartThread");JavaThread *native_thread = NULL;//表示是否有异常 , 当抛出异常时需要获取Heap_lock 。bool throw_illegal_thread_state = false;// 在发布jvmti事件之前 , 必须释放Threads_lock// in Thread::start.{// 获取 Threads_lock锁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 runningjlong size =java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));// 创建JVM线程(用JavaThread对象表示)size_t sz = size > 0 ? (size_t) size : 0;native_thread = new JavaThread(&thread_entry, sz);...}}...Thread::start(native_thread);//启动内核线程JVM_END源码见:
https://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/69087d08d473/src/share/vm/prims/jvm.cpp
我们再来看看JavaThread的实现 , 发现内部通过 os::create_thread(this, thr_type, stack_sz);来调用不同操作系统的创建线程方法创建线程 。
JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :Thread()#if INCLUDE_ALL_GCS, _satb_mark_queue(&_satb_mark_queue_set),_dirty_card_queue(&_dirty_card_queue_set)#endif // INCLUDE_ALL_GCS{if (TraceThreadEvents) {tty->print_cr("creating thread %p", this);}initialize();_jni_attach_state = _not_attaching_via_jni;set_entry_point(entry_point);// Create the native thread itself.// %note runtime_23os::ThreadType thr_type = os::java_thread;thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :os::java_thread;os::create_thread(this, thr_type, stack_sz);//调用不同操作系统的创建线程方法创建线程}源码见:
https://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/69087d08d473/src/share/vm/runtime/thread.cpp
我们都知道Java是跨平台的 , 但是native各种方法底层c/c++代码对各平台都需要有对应的兼容 , 我们这边以linux为例 , 其他平台就大家自行去查阅了
bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {assert(thread->osthread() == NULL, "caller responsible");// Allocate the OSThread objectOSThread* osthread = new OSThread(NULL, NULL);if (osthread == NULL) {return false;}// set the correct thread stateosthread->set_thread_type(thr_type);// Initial state is ALLOCATED but not INITIALIZEDosthread->set_state(ALLOCATED);thread->set_osthread(osthread);// init thread attributespthread_attr_t attr;pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);// stack sizeif (os::Linux::supports_variable_stack_size()) {// calculate stack size if it's not specified by callerif (stack_size == 0) {stack_size = os::Linux::default_stack_size(thr_type);switch (thr_type) {case os::java_thread:// Java threads use ThreadStackSize which default value can be// changed with the flag -Xssassert (JavaThread::stack_size_at_create() > 0, "this should be set");stack_size = JavaThread::stack_size_at_create();break;case os::compiler_thread:if (CompilerThreadStackSize > 0) {stack_size = (size_t)(CompilerThreadStackSize * K);break;} // else fall through:// use VMThreadStackSize if CompilerThreadStackSize is not definedcase os::vm_thread:case os::pgc_thread:case os::cgc_thread:case os::watcher_thread:if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);break;}}stack_size = MAX2(stack_size, os::Linux::min_stack_allowed);pthread_attr_setstacksize(&attr, stack_size);} else {// let pthread_create() pick the default value.}// glibc guard pagepthread_attr_setguardsize(&attr, os::Linux::default_guard_size(thr_type));ThreadState state;{// Serialize thread creation if we are running with fixed stack LinuxThreadsbool lock = os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack();if (lock) {os::Linux::createThread_lock()->lock_without_safepoint_check();}pthread_t tid;//通过pthread_create方法创建内核级线程 !int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);pthread_attr_destroy(&attr);if (ret != 0) {if (PrintMiscellaneous && (Verbose || WizardMode)) {perror("pthread_create()");}// Need to clean up stuff we've allocated so farthread->set_osthread(NULL);delete osthread;if (lock) os::Linux::createThread_lock()->unlock();return false;}// Store pthread info into the OSThreadosthread->set_pthread_id(tid);// Wait until child thread is either initialized or aborted{Monitor* sync_with_child = osthread->startThread_lock();MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);while ((state = osthread->get_state()) == ALLOCATED) {sync_with_child->wait(Mutex::_no_safepoint_check_flag);}}if (lock) {os::Linux::createThread_lock()->unlock();}}// Aborted due to thread limit being reachedif (state == ZOMBIE) {thread->set_osthread(NULL);delete osthread;return false;}// The thread is returned suspended (in state INITIALIZED),// and is started higher up in the call chainassert(state == INITIALIZED, "race condition");return true;}


推荐阅读