Java线程中start与run方法

Java Thread中start方法和run方法的关系

  • 仔细看run方法可以知道,run方法仅仅是Thread中的一个成员方法,那么它是如何与线程的运行挂钩呢?
  • 线程开启之后为什么要执行run方法呢?

要解释上面的问题首先要知道Java开启一个线程的流程
1、API层级

new Thread().start()

2、JDK层级
在Thread中,会导入本地方法库

public class Thread implements Runnable {
    /* Make sure registerNatives is the first thing  does. */
    private static native void registerNatives();
    static {
        registerNatives();
    }

而registerNatives方法在JDK源码中的体现在 openjdk/src/share/native/java/lang/Thread.c
其中映射了很多的本地方法,主要分析start方法

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},
};
JNIEXPORT void JNICALL
Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls)
{
    (*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
}

3、JVM层
JVM_StartThread方法对应着hostspot/src/share/vm/prims/jvm.cpp

JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
  JVMWrapper("JVM_StartThread");
  // ... 栈大小,默认是1M
  jlong size = java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));
  size_t sz = size > 0 ? (size_t) size : 0;
  native_thread = new JavaThread(&thread_entry, sz);
  // ...

4、从这里可以看出在JVM_StartThread中真正创建出了与JVM平台相关的本地线程
thread_entry : 线程函数
sz: 线程栈大小

static void thread_entry(JavaThread* thread, TRAPS) {
  HandleMark hm(THREAD);
  Handle obj(THREAD, thread->threadObj());
  JavaValue result(T_VOID);
  JavaCalls::call_virtual(&result,
                          obj,
                          KlassHandle(THREAD, SystemDictionary::Thread_klass()),
                          vmSymbols::run_method_name(), // 注意这里
                          vmSymbols::void_method_signature(),
                          THREAD);
}

5、这个run_method_name就是指定线程运行的回调方法
hostspot/src/share/vm/classfile/vmSymbols.hpp

template(run_method_name,                           "run")                                      \

到这里是不是就明白了为什么线程启动后会调用run方法。
关于线程是如何创建的逻辑在 /runtime/Thread.cpp

JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
  Thread(){
    os::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);
}

你可能感兴趣的:(Java线程中start与run方法)