设置和获取当前线程名称(线程的基本方法有哪些)
首发

设置和获取当前线程名称(线程的基本方法有哪些)

优质
请用语音读文章

前言

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_END

make_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 对象。

#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();

以上就是由优质生活领域创作者 生活常识网 整理编辑的,如果觉得有帮助欢迎收藏转发~

分享到 :
相关推荐

hosts地址怎么改(如何修改hosts文件)

请用语音读文章Hosts文件在哪里呢?windows中的Hosts文件路径地点都[&...

向女生表白的名言名句(跟女生表白的暖心情话)

请用语音读文章遇见心仪的女生。很多男孩都想知道那些些表白的话都有哪些。表白情书该怎[...

名字游戏ID(有什么好听的游戏ID名字)

请用语音读文章眼前一亮称不上。头皮发麻还是有的。我曾经是《魔兽世界》中一名勇敢的[&...

书香味的香水是哪一种(世上最好的香水是少女体香)

请用语音读文章不同人有着不同的长相、不同的性格。有些人看起来粗犷、有些人则看起来则[...

发表评论

您的电子邮箱地址不会被公开。