Understanding Java 21 Virtual Threads: Basics, Spring Boot Integration, and Performance Comparison
This article introduces Java 21 virtual threads, explains their lightweight, high‑concurrency and automatic management advantages, demonstrates basic and delayed usage with code examples, shows how to enable them in Spring Boot, and compares their performance against traditional threads in various scenarios.
Virtual threads, introduced in Java 21, simplify concurrent programming by providing lightweight, high‑concurrency, and automatically managed threads that are managed by the JVM rather than the operating system.
Lightweight : Virtual threads consume far less memory and have lower creation cost than OS threads, allowing creation of hundreds of thousands of threads.
High Concurrency : Ideal for I/O‑intensive workloads, enabling responsive, high‑throughput applications.
Automatic Management : The JVM schedules virtual threads automatically, removing the need for manual thread‑pool tuning.
Basic Usage of Virtual Threads
Thread virtualThread = Thread.ofVirtual().start(() -> {
System.out.println("虚拟线程正在运行");
});
System.out.println("主线程正在运行");Delayed start example:
Thread virtualThread = Thread.ofVirtual()
.name("虚拟线程")
.unstarted(() -> System.out.println("虚拟线程运行中"));
virtualThread.start();
virtualThread.join(); // wait for completionUsing Virtual Threads in Spring Boot
1. Ensure Java version 21 or higher.
2. Enable preview features in pom.xml :
org.apache.maven.plugins
maven-compiler-plugin
21
21
--enable-preview3. Enable monitoring in application.properties :
management.endpoints.web.exposure.include=health,info,metrics4. Configure Tomcat to use a virtual‑thread executor:
@Bean
public TomcatProtocolHandlerCustomizer
protocolHandlerVirtualThreadExecutorCustomizer() {
return protocolHandler -> protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
}Experiment: Traditional Thread vs Virtual Thread
Creating and joining 100,000 traditional threads takes about 18.6 seconds, while the same workload with virtual threads completes in roughly 3.7 seconds, a performance gain of nearly 5×.
for (int i = 0; i < 100_000; i++) {
Thread thread = new Thread(() -> System.out.println(i));
thread.start();
thread.join();
} for (int i = 0; i < 100_000; i++) {
Thread thread = Thread.ofVirtual().unstarted(() -> System.out.println(i));
thread.start();
thread.join();
}HTTP request benchmark (1600 requests, 400 concurrent): traditional threads took 9.659 s (165.65 req/s) whereas virtual threads took 7.912 s (202.22 req/s), showing higher throughput and lower latency.
Other Java Performance Tips
Use parallel streams ( parallelStream() ) for CPU‑bound tasks.
Leverage CompletableFuture for asynchronous I/O‑bound processing.
Optimize database access with caching (e.g., Redis) to reduce I/O.
Employ object pools such as Apache Commons Pool to minimize object creation overhead.
Conclusion
Virtual threads revolutionize Java concurrency by simplifying management and boosting performance in high‑load scenarios.
They enable creation of massive numbers of threads without degrading application performance.
Integrating virtual threads into Spring Boot requires only a few configuration steps.
Combined with other optimizations like parallel streams and CompletableFuture, they significantly enhance Java application efficiency.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.