Boost Java Performance with Virtual Threads: A Hands‑On Guide
This article explains Java 21's virtual threads, their lightweight and auto‑managed nature, demonstrates basic usage and Spring Boot integration, compares performance against traditional threads, and offers additional Java performance tips for high‑concurrency applications.
Virtual threads, introduced in Java 21, simplify concurrent programming by being lightweight, highly concurrent, and automatically managed by the JVM.
Basic Usage of Virtual Threads
Creating a virtual thread is as simple as using Thread.ofVirtual().start(...):
Thread virtualThread = Thread.ofVirtual().start(() -> {
System.out.println('Virtual thread is running');
});
System.out.println('Main thread is running');Virtual threads can also be created in an unstarted state and started later:
Thread virtualThread = Thread.ofVirtual()
.name('VirtualThread')
.unstarted(() -> System.out.println('Virtual thread running'));
virtualThread.start();
virtualThread.join(); // wait for completionUsing Virtual Threads in Spring Boot
To enable virtual threads in a Spring Boot project, use Java 21 or later and add the --enable-preview flag to the Maven compiler plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>21</source>
<target>21</target>
<compilerArgs>
<arg>--enable-preview</arg>
</compilerArgs>
</configuration>
</plugin>Enable metrics exposure in application.properties:
management.endpoints.web.exposure.include=health,info,metricsConfigure Tomcat to use a virtual‑thread executor:
@Bean
public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
return protocolHandler -> protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
}Experiment: Traditional Threads vs Virtual Threads
1. Creating 100,000 threads
Traditional threads take about 18.6 seconds, while virtual threads finish in roughly 3.7 seconds, a performance gain of nearly 500%.
// Traditional thread loop (simplified)
for (int i = 0; i < 100_000; i++) {
Thread thread = new Thread(() -> System.out.println(i));
thread.start();
thread.join();
}
// Virtual thread loop
for (int i = 0; i < 100_000; i++) {
Thread thread = Thread.ofVirtual().unstarted(() -> System.out.println(i));
thread.start();
thread.join();
}2. HTTP request performance
In a test with 1 600 requests and 400 concurrent clients, traditional threads took 9.659 seconds (165.65 req/s) whereas virtual threads took 7.912 seconds (202.22 req/s), showing higher throughput and lower latency.
Other Java Performance Tips
Parallel streams : Use parallelStream() for CPU‑bound tasks.
Asynchronous programming with CompletableFuture : Reduce blocking I/O.
Database query optimization : Cache frequent data (e.g., Redis).
Memory management : Use object pools such as Apache Commons Pool.
Conclusion
Virtual threads revolutionize Java concurrency by simplifying thread management and dramatically improving performance in high‑concurrency scenarios. They can be enabled in Spring Boot with minimal configuration, and combined with other techniques like parallel streams and CompletableFuture for even greater gains.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.
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.
