概述
在多线程开发中,经常会用到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的地址,就是当前线程的地址;
网友评论