Java线程源码解析之currentThread

概述

在多线程开发中,经常会用到Thread.currentThread方法获取当前线程对象,那么JDK是如何实现的呢?

源码

Thread.currentThread是native方法,调用的是jvm.cpp中的JVM_CurrentThread函数:

JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))
  JVMWrapper("JVM_CurrentThread");
  oop jthread = thread->threadObj();
  assert (thread != NULL, "no current thread!");
  return JNIHandles::make_local(env, jthread);
JVM_END

大家可能奇怪thread是从哪来的,实际上是通过JVM_ENTRY宏定义的:

#define JVM_ENTRY(result_type, header)                               \
extern "C" {                                                         \
  result_type JNICALL header {                                       \
    JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
    ThreadInVMfromNative __tiv(thread);                              \
    debug_only(VMNativeEntryWrapper __vew;)                          \
    VM_ENTRY_BASE(result_type, header, thread)
static JavaThread* thread_from_jni_environment(JNIEnv* env) {
    JavaThread *thread_from_jni_env = (JavaThread*)((intptr_t)env - in_bytes(jni_environment_offset()));
    // Only return NULL if thread is off the thread list; starting to
    // exit should not return NULL.
    if (thread_from_jni_env->is_terminated()) {
       thread_from_jni_env->block_if_vm_exited();
       return NULL;
    } else {
       return thread_from_jni_env;
    }
  }
static ByteSize jni_environment_offset()       { return byte_offset_of(JavaThread, _jni_environment     ); }

为什么(intptr_t)env - in_bytes(jni_environment_offset())得到的就是当前线程的地址呢?

我们看看JavaThread的定义:

class JavaThread: public Thread {
  friend class VMStructs;
 private:
  JavaThread*    _next;                          // The next thread in the Threads list
  oop            _threadObj;                     // The Java level thread object

  JavaFrameAnchor _anchor;                       // Encapsulation of current java frame and it state

  ThreadFunction _entry_point;

  JNIEnv        _jni_environment;
}

可以看到JavaThread里面有线程指针_next,它指向的head元素就是当前线程,因此根据_jni_environment推导出_next的地址,就是当前线程的地址;

你可能感兴趣的:(Java线程源码解析之currentThread)