jvm 线程.currentThread()性能

dpiehjr4  于 2022-11-07  发布在  其他
关注(0)|答案(1)|浏览(230)

我有一个Runnable队列,它在指定的线程中一个接一个地调用。

val queue = LinkedBlockingQueue<() -> Unit>()

val queueThread = thread {
  while(true)
    queue.take().invoke()
}

我也有函数,添加Runnable,并等待它完成。

fun invokeOnQueueThread(toInvoke: () -> Unit){
  if(Thread.currentThread() == queueThread)
    toInvoke()
  else {
    queue.offer(toInvoke)
    // Some waiting code...
  }
}

我测试当前线程是否已经在我队列线程内,以防止不必要的锁定。
所以,问题是:
如果我非常频繁地调用这段代码,Thread.currentThread()会导致性能问题吗?

qv7cva1a

qv7cva1a1#

JDK本身依赖于Thread.currentThread()的性能,因为这个方法在标准Java类库中被广泛使用:特别是在ThreadLocal.getReentrantLock.lock和其他java.util.concurrent原语中。
虽然Thread.currentThread()在OpenJDK中被标记为本机方法,但它并不是真实的的JNI方法,而是JVM内在方法。这意味着,JIT编译器会用高度优化的机器码替换调用。
在大多数CPU架构上(x64、ARM等)HotSpot JVM有一个专用的CPU寄存器,用于保存指向当前线程的指针。不是java.lang.Thread,而是代表Java线程的内部VM结构。反过来,此结构保存对相应java.lang.Thread对象的引用。因此,在JIT编译的代码中,获得对当前线程的引用仅仅是从专用寄存器所指向的结构的单个加载。
例如,在x64上,当执行Java代码时,寄存器R15保存指向当前VM线程的指针,并且Thread.currentThread()调用被编译为类似于

mov  0x280(%r15),%r11

因此,调用Thread.currentThread()并不比阅读常规字段慢,并且不应该是性能问题。

相关问题