线程的创建以及执行代码:
public class ThreadDemo extends Thread{
    @Override
    public void run() {
        System.out.println("当前线程执行的代码");
    }

    public static void main(String[] args) {
         new ThreadDemo().start();
    }
}

此处思考,该线程背后的执行原理。

1.从JAVA层面看start()执行

public synchronized void start() {
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        group.add(this);
        boolean started = false;
        try {
            start0();
            started = true;

主要调用start0()

private native void start0();

2. JAVA native 和 Hostpot映射关系 由于是native 这里转至JVM层面 这里有个技巧,关于JAVA native 和 Hostpot映射关系 http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/00cd9dc3c2b5/src/share/native/java/lang/Thread.c

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},
};

3. 追踪JVM_StartThread 根据映射 追踪JVM_StartThread 方法,进入jvm.cpp

JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
  JVMWrapper("JVM_StartThread");
  JavaThread *native_thread = NULL;
...
  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);
      }
    }
  }
...
  Thread::start(native_thread);

解析: 这里着重调用两个方法,①是构造方法new JavaThread(&thread_entry, sz),②是Thread::start(native_thread)

4. 追踪构造方法new JavaThread(&thread_entry, sz)的参数thread_entry 仍然是jvm.cpp中

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);
}

解析: 我们需要注意call_virtual方法中的几个参数:

obj:就是当前线程对象 vmClasses::Thread_klass():表示调用的对象的类型是java.lang.Thread vmSymbols::run_method_name():表示调用的方法是 run vmSymbols::void_method_signature():表示返回结果是空。 映射关系如下: vmClassMacros.hpp 中

do_klass(Thread_klass,java_lang_Thread)

vmSymbols.hpp 中

template(run_method_name,                           "run")

5. 追踪追踪构造方法new JavaThread(&thread_entry, sz) 仍然是jvm.cpp中

JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
  Thread()
...
  initialize();
  _jni_attach_state = _not_attaching_via_jni;
  set_entry_point(entry_point);
  os::ThreadType thr_type = os::java_thread;
  os::create_thread(this, thr_type, stack_sz);
...
}

解析: 这里关注两个方法 ①调用set_entry_point 就向线程中注册了回调函数;②create_thread 方法在os.hpp文件中

static bool create_thread(Thread* thread, ThreadType thr_type, size_t stack_size = 0);

6. 追踪create_thread 由于Java跨平台性,这里默认展示linux,即os_linux.cpp文件

bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
...
    int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
...
}

解析: 这里调用了java_start方法

7. 追踪java_start方法 仍然在os_linux.cpp文件中

static void *java_start(Thread *thread) {
  ThreadLocalStorage::set_thread(thread);
  OSThread* osthread = thread->osthread();
  Monitor* sync = osthread->startThread_lock();
  if (!_thread_safety_check(thread)) {
    // notify parent thread
    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
    osthread->set_state(ZOMBIE);
    sync->notify_all();
    return NULL;
  }
...
  {
    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
    // notify parent thread
    osthread->set_state(INITIALIZED);
    sync->notify_all();
    // wait until os::start_thread()
    while (osthread->get_state() == INITIALIZED) {
      sync->wait(Mutex::_no_safepoint_check_flag);
    }
  }
  // call one more level start routine
  thread->run();

  return 0;
}

解析: 可以看出将当前当前线程wait,当调用了start_thread()方法的时候。就会唤醒(notify_all()),然后就是回调run(),也就是回调我们刚才向线程中注册的方法。既而指明run方法执行方式是回调执行的。 通过注释表示线程创建后是wait了,在os::start_thread()时notify了。

8. 追踪run() 跟着run() 追踪到thread.cpp,内部执行一个thread_main_inner()

// The first routine called by a new Java thread
void JavaThread::run() {
...
...
  // We call another function to do the rest so we are sure that the stack addresses used
  // from there will be lower than the stack base just computed
  thread_main_inner();

}

9. 追踪thread_main_inner() 依旧在thread.cpp文件中

void JavaThread::thread_main_inner() {
  assert(JavaThread::current() == this, "sanity check");
  assert(this->threadObj() != NULL, "just checking");

  // Execute thread entry point unless this thread has a pending exception
  // or has been stopped before starting.
  // Note: Due to JVM_StopThread we can have pending exceptions already!
  if (!this->has_pending_exception() &&
      !java_lang_Thread::is_stillborn(this->threadObj())) {
    {
      ResourceMark rm(this);
      this->set_native_thread_name(this->get_thread_name());
    }
    HandleMark hm(this);
    this->entry_point()(this, this);
  }

  DTRACE_THREAD_PROBE(stop, this);

  this->exit(false);
  delete this;
}

解析: 在这里看到一个熟悉的方法entry_point() 就是上面 set_entry_point注册回调方法,既而表示run()执行方法是回调执行。

这里有一个疑惑点,就是在第7步解析中看到注释表明线程创建后是wait,在执行os::start_thread()后是notify的。接下里我们就确认这个os::start_thread()后是不是notify了?

10.追踪Thread::start(native_thread) 这里是上述3步骤提到的②Thread::start(native_thread)方法逻辑

void Thread::start(Thread* thread) {
  trace("start", thread);
  if (!DisableStartThread) {
    if (thread->is_Java_thread()) { java_lang_Thread::set_thread_status(((JavaThread*)thread)->threadObj(),
                                          java_lang_Thread::RUNNABLE);
    }
    os::start_thread(thread);
  }
}

11.追踪os::start_thread(thread) 追踪到os_linux.cpp文件中

void os::pd_start_thread(Thread* thread) {
  OSThread * osthread = thread->osthread();
  assert(osthread->get_state() != INITIALIZED, "just checking");
  Monitor* sync_with_child = osthread->startThread_lock();
  MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
  sync_with_child->notify();
}

解析: 这里的最后一行代码已经确认了我们上面提到的疑惑,至此,小伙伴们明白了吗?欢迎大家在评论区留言指正,谢谢。

总结流程图