Thread.currentThread() 表现

Thread.currentThread() performance

我有 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() 会导致性能问题吗?

JDK 本身依赖于 Thread.currentThread() 的性能,因为这种方法在标准 Java class 库中被广泛使用:具体来说,在 ThreadLocal.get, ReentrantLock.lock 和其他 java.util.concurrent 原语。

虽然 Thread.currentThread() 在 OpenJDK 中被标记为本地方法,但它不是真正的 JNI 方法,而是 JVM intrinsic。这意味着,JIT 编译器用高度优化的机器代码替换调用。

在大多数 CPU 架构(x64、ARM 等)上,HotSpot JVM 有一个专用的 CPU 寄存器用于保存指向当前线程的指针。不是 java.lang.Thread,而是表示 Java 线程的内部 VM 结构。反过来,这个结构持有对相应 java.lang.Thread 对象的引用。因此,在 JIT-compiled 代码中,获取对当前线程的引用只是从专用寄存器指向的结构中加载一次。

例如在 x64 上,寄存器 R15 在执行 Java 代码时保存指向当前 VM 线程的指针,并且 Thread.currentThread() 调用被编译为类似于

  mov  0x280(%r15),%r11

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