Master Java 21 Virtual Threads: Creation, Usage, and Best Practices

This article explains Java 21's virtual threads, their lightweight nature, and provides step‑by‑step code examples for creating and managing them via static builders, ExecutorService, and thread factories, helping developers improve concurrency and scalability in Java applications.

Programmer DD
Programmer DD
Programmer DD
Master Java 21 Virtual Threads: Creation, Usage, and Best Practices

Java 21 introduces virtual threads (also known as user‑mode threads or fibers) to simplify and enhance concurrency, offering lightweight, highly scalable threads that reduce overhead compared to traditional threads.

Creating and Using Virtual Threads

There are several ways to create and use virtual threads in Java 21:

1. Using the static builder method

The Thread.startVirtualThread method takes a Runnable and starts a virtual thread immediately:

Runnable runnable = () -> {
    System.out.println("Hello, www.didispace.com");
};
// Using the static builder method
Thread virtualThread = Thread.startVirtualThread(runnable);

You can also use Thread.ofVirtual() to create a virtual thread with additional properties such as a name:

Thread.ofVirtual()
        .name("didispace-virtual-thread")
        .start(runnable);

2. Combining with ExecutorService

Since Java 5, developers have been encouraged to use ExecutorService instead of directly creating Thread objects. Java 21 adds support for virtual threads in executors. The following example creates a virtual‑thread‑per‑task executor and submits many tasks:

Runnable runnable = () -> {
    System.out.println("Hello, www.didispace.com");
};
try (ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor()) {
    for (int i = 0; i < 100; i++) {
        executorService.submit(runnable);
    }
}

This code creates an ExecutorService that generates a virtual thread for each submitted task.

3. Using a virtual‑thread factory

Developers can also create a factory that produces virtual threads, allowing centralized configuration such as naming patterns:

Runnable runnable = () -> {
    System.out.println("Hello, www.didispace.com");
};
ThreadFactory virtualThreadFactory = Thread.ofVirtual()
        .name("didispace", 0)
        .factory();
Thread factoryThread = virtualThreadFactory.newThread(runnable);
factoryThread.start();

The factory creates virtual threads whose names start with the prefix didispace followed by an incrementing number.

Key Takeaways

Virtual threads are lightweight threads managed by the JVM.

They require no explicit allocation or scheduling by the programmer.

Virtual threads excel at I/O‑bound or highly parallel workloads.

They can also be used to implement asynchronous operations.

While virtual threads greatly improve concurrency and scalability, they may not be optimal for CPU‑intensive tasks due to context‑switch overhead; performance should be evaluated per scenario.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaconcurrencyVirtual ThreadsJava 21Thread API
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.