ReviseAlgo Logo

Modern Java Features

Virtual Threads

Understand Java 21 Virtual Threads (Project Loom) for high-scale concurrency.

Interview: Highly tested: platform threads vs virtual threads, thread pinning, and why thread pooling is an anti-pattern for virtual threads.

Last Updated: June 13, 2026 12 min read

Introduced in Java 21, Virtual Threads (Project Loom) are lightweight threads mapped dynamically to carrier OS threads. They enable high-throughput applications using simple thread-per-request blocking APIs.

Core Idea

Virtual threads are managed by the JVM, not the OS. Blocking calls yield execution without blocking the underlying OS thread.

Why It Matters

Allows running millions of concurrent threads, bypassing the memory bottlenecks of platform threads.

Interview Lens

Expect deep dives into carrier thread mechanics, thread pinning, and why pooling virtual threads is unnecessary.

Platform vs. Virtual Threads

  • Platform Threads: 1-to-1 mapping with native OS threads. Resource-intensive (allocating 1MB stack by default). Limited to a few thousand instances.
  • Virtual Threads: Mapped to a ForkJoinPool of carrier OS threads. Stack frames are stored on the JVM heap. Virtual threads are cheap to create, meaning you should never pool them; just create a new thread for each task.
  • Thread Pinning: Occurs when a virtual thread is pinned to its carrier thread, preventing other virtual threads from running. Pinning is caused by executing code inside a synchronized block or calling native code (JNI). Use ReentrantLock instead of synchronized to prevent pinning.

Code Walkthrough

This program demonstrates creating and executing virtual threads.

import java.util.concurrent.Executors;

public class VirtualThreadDemo { public static void main(String[] args) throws Exception { // Create an executor that spawns a new virtual thread for each task try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { for (int i = 0; i < 10000; i++) { executor.submit(() -> { // Simulates non-blocking blocking I/O: JVM yields OS thread automatically Thread.sleep(100); return null; }); } } // Executor close blocks until all tasks complete System.out.println("All tasks finished!"); } }

Interview-Relevant Information

Q: Why is pooling virtual threads an anti-pattern?
Answer: Thread pools are designed to throttle resource consumption because platform threads are expensive. Virtual threads are lightweight, disposable resources. Pooling them defeats their purpose. If you need to limit concurrency to a resource (like a database connection pool), use a Semaphore instead of pooling threads.

Quick Checklist

Where are virtual thread stack frames stored? What is thread pinning, and how do you resolve it? If yes, you understand Virtual Threads.

Use Cases

Handling thousands of parallel database and HTTP transactions inside microservices.

Simplifying asynchronous pipelines using blocking code models.

Common Mistakes

Pooling virtual threads using ThreadPoolExecutor configurations.

Keeping synchronized blocks on long-running database requests, causing thread pinning bottlenecks on carrier threads.