I have Runnable queue that invokes one by one in specified thread.
val queue = LinkedBlockingQueue<() -> Unit>()
val queueThread = thread {
while(true)
queue.take().invoke()
}
Also I have function that adds Runnable and wait for it to complete.
fun invokeOnQueueThread(toInvoke: () -> Unit){
if(Thread.currentThread() == queueThread)
toInvoke()
else {
queue.offer(toInvoke)
// Some waiting code...
}
}
I test if current thread is already inside my queue's thread to prevent unnecessary locking itself.
So, the question is:
Will Thread.currentThread()
cause performance issues if I call this code very, very often?
CodePudding user response:
JDK itself relies on the performance of Thread.currentThread()
, as this method is widely used in the standard Java class library: specifically, in ThreadLocal.get
, ReentrantLock.lock
and in other java.util.concurrent primitives.
Although Thread.currentThread()
is marked as a native method in OpenJDK, it is not a real JNI method, but rather a JVM intrinsic. This means, JIT compiler replaces the call with a highly optimized machine code.
On most CPU architectures (x64, ARM, etc.) HotSpot JVM has a dedicated CPU register for holding a pointer to the current thread. Not a java.lang.Thread
, but an internal VM structure representing a Java thread. In turn, this structure holds a reference to the corresponding java.lang.Thread
object. So, in the JIT-compiled code, getting a reference to the current thread is just a single load from a structure pointed by a dedicated register.
E.g. on x64 the register R15 holds a pointer to the current VM thread while executing Java code, and Thread.currentThread()
call is compiled to something like
mov 0x280(%r15),%r11
Therefore calling Thread.currentThread()
is not slower than reading a regular field, and should not be a performance issue.