设置和获取当前线程名称 java代码大全及详解

前言
java 中经常会遇到要获取当前线程的情况 。这时一般我们就会通过Thread.currentThread()来获取 。接下去就看看执行该语句在 JVM 中做了什么吧 。
简单例子
以下是一个简单的例子 。获取当前线程并打印线程名称 。输出是”main” 。即主线程 。
publicclassCurrentThreadTest{publicstaticvoidmain(String[]args){Threadt=Thread.currentThread();System.out.println(t.getName());}}currentThread方法
在 Thread 类中 。currentThread是一个静态且本地方法 。
publicstaticnativeThreadcurrentThread();Thread.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函数
#defineTHD"Ljava/lang/Thread;"staticJNINativeMethodmethods[]={...{"currentThread","()"THD,(void*)&JVM_CurrentThread},...};JVM_ENTRY(jobject,JVM_CurrentThread(JNIEnv*env,jclassthreadClass))JVMWrapper("JVM_CurrentThread");oopjthread=thread->threadObj();assert(thread!=NULL,"nocurrentthread!");returnJNIHandles::make_local(env,jthread);JVM_ENDmake_local函数中主要看thread_from_jni_environment函数 。它用于获取当前线程 。它的逻辑为JavaThread *thread_from_jni_env = (JavaThread*)((intptr_t)env – in_bytes(jni_environment_offset())); 。即直接通过地址偏移来做减法计算得到JavaThread* 。这是因为 JavaThread 对象包含了 JNIEnv 对象属性 。所以可以通过JNIEnv*与偏移做减法来算出JavaThread* 。最后还要检查线程是否已经终止状态 。没有终止才返回该线程对象 。
获取到JavaThread*对象后 。分配句柄并将 oop 赋给句柄 。并且转成 Java 层的对象 jobject 。
jobjectJNIHandles::make_local(JNIEnv*env,oopobj){if(obj==NULL){returnNULL;}else{JavaThread*thread=JavaThread::thread_from_jni_environment(env);assert(Universe::heap()->is_in_reserved(obj),"sanitycheck");returnthread->active_handles()->allocate_handle(obj);}}staticJavaThread*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();returnNULL;}else{returnthread_from_jni_env;}}`JNI_ENTRY`和`JNI_END`宏
这两个宏将共同的部分都抽离出来了 。其中JNI_END比较简单 。就两个结束大括号 。
#defineJNI_ENTRY(result_type,header)JNI_ENTRY_NO_PRESERVE(result_type,header)WeakPreserveExceptionMark__wem(thread);#defineJNI_END}}JNI_ENTRY主要逻辑:
获取当前执行线程 JavaThread 指针对象 。
创建 ThreadInVMfromNative 对象 。
TRACE_CALL。这里什么都不干 。
创建 HandleMarkCleaner 对象 。
将 thread 赋值给 Exceptions 中的 THREAD 。
校验栈对齐 。
创建 WeakPreserveExceptionMark 对象 。
【设置和获取当前线程名称 java代码大全及详解】#defineJNI_ENTRY_NO_PRESERVE(result_type,header)\extern"C"{\result_typeJNICALLheader{\JavaThread*thread=JavaThread::thread_from_jni_environment(env);\assert(!VerifyJNIEnvThread||(thread==Thread::current()),"JNIEnvisonlyvalidinsamethread");\ThreadInVMfromNative__tiv(thread);\debug_only(VMNativeEntryWrapper__vew;)\VM_ENTRY_BASE(result_type,header,thread)#defineVM_ENTRY_BASE(result_type,header,thread)\TRACE_CALL(result_type,header)\HandleMarkCleaner__hm(thread);\Thread*THREAD=thread;\os::verify_stack_alignment();

    推荐阅读