Chaturmind
LearnDSASystem DesignBlogPremium
Sign inGet started
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML

Company

  • Blog
  • Premium
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Java 21 — New Features

Data-Oriented Programming

  • Records
  • Sealed Classes
  • Pattern Matching

Virtual Threads (Project Loom)

  • Virtual Threads
Chaturmind
← Java 21 — New Features

Data-Oriented Programming

  • Records
  • Sealed Classes
  • Pattern Matching

Virtual Threads (Project Loom)

  • Virtual Threads
HomeLearnJavaJava 21 — New FeaturesVirtual Threads (Project Loom)
✓ FreeAdvanced· 12 min read

Virtual Threads

Millions of cheap threads — how Project Loom changes Java server-side concurrency.

Published February 20, 2025


Virtual Threads (Java 21)

The Problem with Platform Threads

A traditional Java thread maps 1:1 to an OS thread. OS threads are expensive:

  • ~1 MB of stack memory each
  • Context switches are OS-level (slow)
  • A server with 200 concurrent requests needs 200 OS threads

This is why Node.js and reactive frameworks (WebFlux) were invented — to handle more concurrent requests without more threads.

Virtual Threads — the solution

Virtual threads are lightweight, JVM-managed threads:

  • ~1 KB of heap per virtual thread (vs ~1 MB for platform threads)
  • Scheduled by the JVM on a small pool of carrier threads
  • When a virtual thread blocks (I/O, sleep), the carrier thread is unmounted and used for another virtual thread
// 100,000 virtual threads — this works
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 100_000).forEach(i ->
        executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1)); // blocks virtual thread, not OS thread
            System.out.println("Done: " + i);
        })
    );
}
// Completes in ~1 second — all 100K sleep concurrently

Enabling in Spring Boot

spring:
  threads:
    virtual:
      enabled: true

With this property, Spring Boot replaces its Tomcat thread pool with virtual threads. Each incoming HTTP request runs on its own virtual thread.

When Virtual Threads Help

✅ I/O-bound workloads: REST calls, DB queries, file reads — virtual threads shine here

❌ CPU-bound workloads: image processing, cryptography — virtual threads don't help because the carrier thread is occupied the entire time

Structured Concurrency (Java 21 preview)

try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
    Future<User>  user  = scope.fork(() -> fetchUser(userId));
    Future<Order> order = scope.fork(() -> fetchOrder(orderId));
    scope.join();   // wait for both
    scope.throwIfFailed();
    return new Response(user.resultNow(), order.resultNow());
}

Structured concurrency ensures child tasks are cleaned up when the parent scope exits — no more fire-and-forget threads.

Interview Tip

"Virtual threads eliminate the need for reactive programming for I/O-bound workloads. They let you write blocking-style synchronous code that performs like async code — without the complexity of CompletableFuture chains or WebFlux."

Key caveat: avoid synchronised blocks with virtual threads. synchronized pins the virtual thread to its carrier thread, negating the benefit. Use ReentrantLock instead.

Previous

Pattern Matching

AI Tutor

Lesson: Virtual Threads

Quick actions

AI responses can be inaccurate. Verify critical information.