Reputation: 1350
When using virtual threads in IntelliJ, the thread name is not displayed correctly in the debugger, even when explicitly set. Instead, it shows a default name like pool-1-thread-1
.
final ThreadFactory factory = Thread.ofVirtual().name("named-thread-", 0).factory();
final ExecutorService executor = Executors.newThreadPerTaskExecutor(factory);
executor.execute(() -> Thread.currentThread().getName())
The thread name should be displayed as named-thread-0
in the console output and on Intellij Debugger.
The thread name is displayed correctly in the console output as named-thread-0
, but in the IntelliJ debugger, it shows as pool-3-thread-1
.
If I change the code to use a normal thread instead of a virtual thread, the thread name appears correctly in the debugger.
Edit
With @Basil Bourque example, it stills have the same behaviour:
On Console
Upvotes: 1
Views: 73
Reputation: 339837
The name appears in the title under Threads & Variables in IntelliJ IDEA 2025.1 EAP.
I wrote an example app, using basically your code. I changed the name to "my-own-named-thread" plus the counter.
package work.basil.example.threading;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class VirtualThreadName
{
final String whatever = "blah";
public static void main ( String[] args )
{
System.out.println ( "Demo start at " + Instant.now ( ) );
System.out.println ( Runtime.version ( ) );
final ThreadFactory factory = Thread.ofVirtual ( ).name ( "my-own-named-thread-" , 0 ).factory ( );
try (
final ExecutorService executor = Executors.newThreadPerTaskExecutor ( factory )
)
{
executor.execute ( ( ) -> {
System.out.println ( Thread.currentThread ( ).getName ( ) );
Instant now = Instant.now ( );
try { Thread.sleep ( Duration.ofMinutes ( 7 ) ); } catch ( InterruptedException e ) { throw new RuntimeException ( e ); }
} );
try { Thread.sleep ( Duration.ofMinutes ( 7 ) ); } catch ( InterruptedException e ) { throw new RuntimeException ( e ); }
}
System.out.println ( "Demo done at " + Instant.now ( ) );
}
}
Execution:
Instant now = Instant.now ( );
line.Here is a screenshot.
Be aware that calling Executor#execute
(inherited by ExecutorService
) may or may not run your task on a background thread (see Javadoc). To ensure that your task runs on a background thread, call ExecutorService#submit
or similar method on that sub-interface rather than execute
on its super-interface.
Upvotes: 1