Introducing Java 21 Virtual Threads: Basics, Spring Boot Integration, and Performance Comparison
This article explains Java 21 virtual threads, demonstrates how to create and use them in plain Java and Spring Boot, compares their performance against traditional threads in large‑scale and HTTP workloads, and offers additional Java performance optimization tips.
Virtual threads, introduced in Java 21, are a lightweight alternative to OS threads, offering lower memory usage, high concurrency, and automatic management.
Basic Usage of Virtual Threads
Creating a virtual thread is straightforward; the example below shows how to start a virtual thread and print messages from both the virtual and main threads.
Thread virtualThread = Thread.ofVirtual().start(() -> {
System.out.println("虚拟线程正在运行");
});
System.out.println("主线程正在运行");Virtual threads can also be created in a delayed‑start fashion:
Thread virtualThread = Thread.ofVirtual()
.name("虚拟线程")
.unstarted(() -> System.out.println("虚拟线程运行中"));
virtualThread.start();
virtualThread.join(); // 等待虚拟线程完成Using Virtual Threads in Spring Boot
To enable virtual threads in a Spring Boot project, ensure Java 21+, enable preview features in pom.xml , configure performance monitoring, and set up a virtual‑thread executor for Tomcat.
org.apache.maven.plugins
maven-compiler-plugin
21
21
--enable-preview @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 complete in roughly 3.7 seconds, a performance gain of nearly 500%.
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();
}2. HTTP Request Performance
In a test of 1 600 HTTP requests with 400 concurrent connections, 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
Additional techniques include using parallel streams, CompletableFuture for asynchronous I/O, optimizing database queries with caching, and employing object pools such as Apache Commons Pool.
List
numbers = Arrays.asList(1,2,3,4,5);
numbers.parallelStream().forEach(number -> {
System.out.println(number * 2);
}); CompletableFuture
future = CompletableFuture.runAsync(() -> {
// 异步执行任务
System.out.println("异步任务完成");
});
future.join(); // 等待任务完成Conclusion
Virtual threads simplify concurrency, enable massive thread counts, and improve performance in high‑concurrency Spring Boot applications; combined with other optimizations they further boost Java application efficiency.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
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.