Understanding Java Virtual Threads and Their Performance in Spring Boot
This article explains Java virtual threads introduced in Java 19, compares them with traditional OS threads, shows how to enable them in Spring Boot, and presents performance benchmarks that demonstrate dramatic latency reductions for I/O‑bound workloads.
What are virtual threads? Virtual threads, added in Java 19, are lightweight threads managed by the JVM rather than the operating system, allowing a single OS thread to multiplex thousands of virtual threads, similar to Go's goroutines.
Difference from regular threads Virtual threads consume far less memory, enabling the creation of millions of concurrent threads, whereas traditional threads are heavyweight and limited by OS resources.
Spring Boot usage By using Java 20 and Spring Boot 3.1.2, virtual threads can be enabled with a simple configuration:
/**
* Configuration for testing; set spring.virtual-thread=true to use virtual threads.
*/
@Configuration
@ConditionalOnProperty(prefix = "spring", name = "virtual-thread", havingValue = "true")
public class ThreadConfig {
@Bean
public AsyncTaskExecutor applicationTaskExecutor() {
return new TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor());
}
@Bean
public TomcatProtocolHandlerCustomizer<?> protocolHandlerCustomizer() {
return protocolHandler -> {
protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
};
}
}@Async performance comparison An async service that sleeps for 50 ms was invoked 100 000 times. Using regular threads took about 678 seconds, while virtual threads completed in roughly 3.9 seconds – an improvement of nearly 200×.
@Service
public class AsyncService {
/**
* Simulated I/O operation.
*/
@Async
public void doSomething(CountDownLatch countDownLatch) throws InterruptedException {
Thread.sleep(50);
countDownLatch.countDown();
}
} @Test
public void testAsync() throws InterruptedException {
long start = System.currentTimeMillis();
int n = 100000;
CountDownLatch countDownLatch = new CountDownLatch(n);
for (int i = 0; i < n; i++) {
asyncService.doSomething(countDownLatch);
}
countDownLatch.await();
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "ms");
}HTTP request performance comparison A simple GET endpoint that sleeps 50 ms was stress‑tested with 500 concurrent threads for 10 000 requests. Regular threads showed median latencies above 150 ms due to thread pool exhaustion, while virtual threads kept maximum latency below 100 ms, demonstrating far better resource utilization.
@RequestMapping("/get")
public Object get() throws Exception {
Thread.sleep(50);
return "ok";
}Conclusion Virtual threads provide substantial performance gains for I/O‑bound workloads, reducing latency and improving scalability. They are especially beneficial for typical web applications that spend most of their time waiting on database, cache, or network I/O. For CPU‑bound tasks, the advantage may be less pronounced.
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.
Top Architecture Tech Stack
Sharing Java and Python tech insights, with occasional practical development tool tips.
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.
