在Java中,大家时常会碰到获得当今进程的状况。此刻大家一般根据Thread.currentThread()来获得。使我们一起来看看在JVM中实行这一句子时干了哪些。

简易的事例

下边是一个简易的事例。获得当今进程并打印进程名字。輸出是“main”,即主线任务程。

public class CurrentThreadTest { public static void main(String[] args) { Thread t = Thread.currentThread(); System.out.println(t.getName()); }}

CurrentThread方式

在Thread类中,currentThread是一个静态数据的当地方式。

public static native Thread currentThread();

进程c

Java层申明的部分方式在Thread.c currentThread中完成,是在JVM中申请注册的方式,在JVM中关联到JVM_CurrentThread涵数,因此完成逻辑性在JVM_CurrentThread涵数中。逻辑性是:

JVMWrapper(“JVM_CurrentThread”)用以调节。根据thread->threadObj()获得 oop,这儿的 thread 是在JNI_ENTRY宏中得到的,具体情况可参照后边的JNI_ENTRY和JNI_END宏。启用JNIHandles::make_local涵数#define THD "Ljava/lang/Thread;"static JNINativeMethod methods[] = { ... {"currentThread", "()" THD, (void *)&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

make_local涵数关键看thread_from_jni_environment涵数,用以获得当今进程,其逻辑性为Java thread * thread _ from _ JNI _ env =(Java thread *)((int ptr _ t)env–in _ bytes(JNI _ environment _ offset())));换句话说,立即减掉详细地址偏移就可以获得javashread *了,由于javashread目标包括jniev目标的特性,因此javashread *能够根据减掉JNIEnv *和偏移来测算。最终,查验进程是不是早已停止,要是没有停止,回到进程目标。

获得JavaThread*目标后,分派返回值,并为返回值分派oop,将其转换为Java层目标JobProject。

jobject JNIHandles::make_local(JNIEnv* env, oop obj) { if (obj == NULL) { return NULL; } else { JavaThread* thread = JavaThread::thread_from_jni_environment(env); assert(Universe::heap()->is_in_reserved(obj), "sanity check"); return thread->active_handles()->allocate_handle(obj); }}static JavaThread* thread_from_jni_environment(JNIEnv* env) { JavaThread *thread_from_jni_env = (JavaThread*)((intptr_t)env - in_bytes(jni_environment_offset())); if (thread_from_jni_env->is_terminated()) { thread_from_jni_env->block_if_vm_exited(); return NULL; } else { return thread_from_jni_env; } }

` JNI _通道'和` JNI _完毕'宏。

这两个宏除掉了公共性一部分。在其中,JNI_END非常简单,仅有2个右大括号。

#define JNI_ENTRY(result_type, header) JNI_ENTRY_NO_PRESERVE(result_type, header) WeakPreserveExceptionMark ._wem(thread);#define JNI_END } }

JNI条目地关键逻辑性:

获得当今实行进程 JavaThread 表针目标。建立 ThreadInVMfromNative 目标。TRACE_CALL ,这儿任何东西都不干。建立 HandleMarkCleaner 目标。将 thread 取值给 Exceptions 中的 THREAD。校检栈两端对齐。建立 WeakPreserveExceptionMark 目标。#define JNI_ENTRY_NO_PRESERVE(result_type, header) \extern "C" { \ result_type JNICALL header { \ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \ ThreadInVMfromNative ._tiv(thread); \ debug_only(VMNativeEntryWrapper ._vew;) \ VM_ENTRY_BASE(result_type, header, thread)#define VM_ENTRY_BASE(result_type, header, thread) \ TRACE_CALL(result_type, header) \ HandleMarkCleaner ._hm(thread); \ Thread* THREAD = thread; \ os::verify_stack_alignment();

评论(0条)

刀客源码 游客评论