4

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
fascynacja
  • 1,625
  • 4
  • 17
  • 35
  • According to [this article](https://blogs.oracle.com/javamagazine/post/java-loom-virtual-threads-platform-threads) thread local will still be an instance local to the currently executing virtual thread. – matt May 05 '23 at 08:56
  • @matt great article, puts more light on the topic – fascynacja May 05 '23 at 08:59

2 Answers2

3

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.

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
1

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
fascynacja
  • 1,625
  • 4
  • 17
  • 35
  • 1
    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. – Solomon Slow May 05 '23 at 10:23
  • 5
    The [Thread](https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/Thread.html) javadoc says that virtual threads have no name by default. – matt May 05 '23 at 10:44
  • @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? – fascynacja May 05 '23 at 11:11
  • @matt 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. – Solomon Slow May 05 '23 at 13:26