Thread.currentThread().getName() returns empty string "" for Virtual Threads created via Executors.newVirtualThreadPerTaskExecutor()
Asked Answered
R

2

14

I am working with Java 19. I have tried to use newly introduced virtual threads as follows:

public static void main(String[] args)  {

    System.out.println("Started with virutal threads");
    try (ExecutorService virtualService = Executors.newVirtualThreadPerTaskExecutor()) {
        virtualService.submit(() -> System.out.println("[" + Thread.currentThread().getName() + "] virtual task 1"));
        virtualService.submit(() -> System.out.println("[" + Thread.currentThread().getName() + "] virtual task 2"));
    }
    System.out.println("Finished");
}

The output of this program is:

Started with virutal threads
[] virtual task 2
[] virtual task 1
Finished

Why Thread.currentThread().getName() does not have any name?

Followup question: How to identify virtual threads between eachother? (how to recognize them) So the output would look like

[thread-1] virtual task 2
[thread-0] virtual task 1
Racism answered 5/5, 2023 at 8:51 Comment(2)
According to this article thread local will still be an instance local to the currently executing virtual thread.Chefoo
@Chefoo great article, puts more light on the topicRacism
S
7

tl;dr

long threadId = Thread.currentThread().threadId() ;  // The thread ID is unique and remains unchanged during its lifetime.

Thread name optional

The name of any thread is entirely optional.

You may name a thread if you so desire. This can be handy while debugging. But you should not expect any preset value.

Virtual threads in particular are specified as having no set name. To quote the Javadoc (my emphasis):

Virtual threads do not have a thread name by default. The getName method returns the empty string if a thread name is not set.

Some frameworks, such as JavaFX/OpenJFX, give their threads an informative name.

Thread ID

If you want to identify a Thread, use its ID, a long.

To quote the Javadoc:

Returns the identifier of this Thread. The thread ID is a positive long number generated when this thread was created. The thread ID is unique and remains unchanged during its lifetime.

Stringendo answered 5/5, 2023 at 15:25 Comment(2)
I don't know why I got so stuck on the "name" that I have forgotten about "id".Racism
@Racism I’ve done the same!Stringendo
R
6

I am still not sure why the thread name is empty but the solution which I found for the moment might be to use ThreadFactory as follows:

    final ThreadFactory factory = Thread.ofVirtual().name("named-thread-", 0).factory();
    try (var virtualService = Executors.newThreadPerTaskExecutor(factory)) {
        virtualService.submit(() -> System.out.println("[" + Thread.currentThread().getName() + "] virtual task 1"));
        virtualService.submit(() -> System.out.println("[" + Thread.currentThread().getName() + "] virtual task 2"));
    } 

In this case the output is:

[named-thread-0] virtual task 1
[named-thread-1] virtual task 2
Racism answered 5/5, 2023 at 9:25 Comment(4)
I don't see anything in the javadoc that requires every thread created by newVirtualThreadPerTaskExecutor to have a unique name. There may be no better solution than this one if you require unique names. Thread names were never meant for any purpose except debugging. The JVM never depended on them in any way.Hardy
The Thread javadoc says that virtual threads have no name by default.Chefoo
@Solomon Slow yes indeed I use the thread names for debugging and for logging. Honestly in some cases the logs without thread name would be useless for me. The thing is that imho we all got used to the fact that the platform threads created by executor service have a name assigned by default, so why the difference when creating virtual threads?Racism
@Chefoo Re, "...no name by default." My hopeful self says that maybe virtual threads really are so cheap to create that even just allocating a new name string for each one would be a significant addititon to the overhead.Hardy

© 2022 - 2024 — McMap. All rights reserved.