Boost Java Concurrency: How Project Loom’s Virtual Threads Supercharge Spring Boot

This article explains Project Loom’s virtual threads, shows how to enable them in a Spring Boot 3.1 application with Java 20, provides code samples and performance test results that demonstrate dramatically higher throughput under high concurrency.

macrozheng
macrozheng
macrozheng
Boost Java Concurrency: How Project Loom’s Virtual Threads Supercharge Spring Boot

What is Project Loom?

Project Loom is an Oracle initiative that aims to dramatically reduce the effort required to write, maintain, and observe high‑throughput concurrent applications by introducing lightweight virtual threads managed by the JVM, making a "one‑thread‑per‑request" model practical.

How to Use Virtual Threads

Java Version Selection

Virtual threads are available starting with Java 19. The author uses the Azul Zulu distribution version 20.30.11 on a Mac M1.

Create a Test Project

Generate a Spring Boot project via Spring Initializr or an IDE, add the spring-web dependency, and use Spring Boot 3.1 with Java 20.

Enable Virtual Thread Support

Virtual thread support is disabled by default in Java 19 and must be enabled via Maven compiler arguments.

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <compilerArgs>--enable-preview</compilerArgs>
  </configuration>
</plugin>

Enable virtual threads by configuring a bean

@Bean
TomcatProtocolHandlerCustomizer<?> threadExecutorCustomizer() {
  return protocolHandler -> protocolHandler.setExecutor(
    Executors.newVirtualThreadPerTaskExecutor());
}

The bean customizes Tomcat’s protocol handler to use an executor that creates a virtual thread for each task, allowing massive concurrency with minimal overhead.

Add a Test Endpoint

@Slf4j
@RequestMapping
@RestController
public class DemoController {
  @GetMapping("/")
  public String demo() {
    try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { log.error(e.getMessage()); }
    return "Current Thread Name: " + Thread.currentThread();
  }
}

Calling Thread.currentThread() lets you verify that the request is handled by a virtual thread.

Performance Test Comparison

100‑Thread Test

Without virtual threads

Throughput: 300 req/s

With virtual threads

Throughput: 300 req/s

300‑Thread Test

Without virtual threads

Throughput: 650 req/s

With virtual threads

Throughput: 950 req/s

500‑Thread Test

Without virtual threads

Throughput: 650 req/s

With virtual threads

Throughput: 1500 req/s

Summary

Virtual threads greatly improve performance for blocking operations, and the benefit becomes more pronounced as the number of concurrent requests increases. The tests were conducted without additional Spring Boot tuning.

References

[1] Azul Zulu Distribution 20.30.11: https://www.azul.com/downloads/?version=java-20-sts&os=macos&architecture=arm-64-bit&package=jdk#zulu

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.

Performance TestingSpring BootVirtual ThreadsProject LoomJava concurrency
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

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.