{ System.out.println("Running on: " + Thread.currentThread()); }); // Per-task executor — one virtual thread per submitted task try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { IntStream.range(0, 100_000).forEach(i -> executor.submit(() -> { Thread.sleep(Duration.ofMillis(100)); // parks, not blocks carrier return i * i; })); } // executor.close() waits for all tasks When a virtual thread blocks on I/O or Thread.sleep(), the JVM parks it (saves its continuation to the heap) and reassigns the carrier thread to another runnable virtual thread — no OS thread is held idle. This is fundamentally different from reactive/async programming: you write simple blocking code and the JVM handles the event-loop-like scheduling transparently. Key constraints: Synchronized blocks pin the virtual thread to its carrier (no parking during a synchronized block). Use java.util.concurrent.locks.ReentrantLock instead of synchronized in hot paths to avoid pinning. Thread-locals work but can cause high memory usage at scale — prefer Scoped Values (JEP 446)."> { System.out.println("Running on: " + Thread.currentThread()); }); // Per-task executor — one virtual thread per submitted task try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { IntStream.range(0, 100_000).forEach(i -> executor.submit(() -> { Thread.sleep(Duration.ofMillis(100)); // parks, not blocks carrier return i * i; })); } // executor.close() waits for all tasks When a virtual thread blocks on I/O or Thread.sleep(), the JVM parks it (saves its continuation to the heap) and reassigns the carrier thread to another runnable virtual thread — no OS thread is held idle. This is fundamentally different from reactive/async programming: you write simple blocking code and the JVM handles the event-loop-like scheduling transparently. Key constraints: Synchronized blocks pin the virtual thread to its carrier (no parking during a synchronized block). Use java.util.concurrent.locks.ReentrantLock instead of synchronized in hot paths to avoid pinning. Thread-locals work but can cause high memory usage at scale — prefer Scoped Values (JEP 446)." />

Prev Next

Java / Java 21 Interview Questions

What are Virtual Threads in Java 21 and how do they differ from Platform Threads?

Virtual Threads (JEP 444) are lightweight threads managed by the JVM rather than the operating system. A platform (OS) thread maps 1:1 to a kernel thread and consumes roughly 1–2 MB of stack memory each, limiting practical concurrency to a few thousand threads per JVM. Virtual threads are multiplexed over a small pool of carrier (platform) threads by the JVM scheduler, consuming only a few hundred bytes of heap per thread, enabling millions of concurrent threads in the same process.

Platform Threads vs Virtual Threads
AspectPlatform ThreadVirtual Thread
Managed byOS kernelJVM (Project Loom)
Memory (stack)~1–2 MB each~few hundred bytes (heap)
Max practical countThousandsMillions
Blocking I/OBlocks OS threadParks virtual thread; carrier thread freed
CreationThread / ExecutorServiceThread.ofVirtual() / Executors.newVirtualThreadPerTaskExecutor()
// Creating a virtual thread directly
Thread vt = Thread.ofVirtual().name("my-vt").start(() -> {
    System.out.println("Running on: " + Thread.currentThread());
});

// Per-task executor — one virtual thread per submitted task
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 100_000).forEach(i ->
        executor.submit(() -> {
            Thread.sleep(Duration.ofMillis(100)); // parks, not blocks carrier
            return i * i;
        }));
} // executor.close() waits for all tasks

When a virtual thread blocks on I/O or Thread.sleep(), the JVM parks it (saves its continuation to the heap) and reassigns the carrier thread to another runnable virtual thread — no OS thread is held idle. This is fundamentally different from reactive/async programming: you write simple blocking code and the JVM handles the event-loop-like scheduling transparently.

Key constraints: Synchronized blocks pin the virtual thread to its carrier (no parking during a synchronized block). Use java.util.concurrent.locks.ReentrantLock instead of synchronized in hot paths to avoid pinning. Thread-locals work but can cause high memory usage at scale — prefer Scoped Values (JEP 446).

What happens when a virtual thread calls Thread.sleep() or performs blocking I/O in Java 21?
Which Java 21 API creates an executor that gives each submitted task its own virtual thread?

Invest now in Acorns!!! 🚀 Join Acorns and get your $5 bonus!

Invest now in Acorns!!! 🚀
Join Acorns and get your $5 bonus!

Earn passively and while sleeping

Acorns is a micro-investing app that automatically invests your "spare change" from daily purchases into diversified, expert-built portfolios of ETFs. It is designed for beginners, allowing you to start investing with as little as $5. The service automates saving and investing. Disclosure: I may receive a referral bonus.

Invest now!!! Get Free equity stock (US, UK only)!

Use Robinhood app to invest in stocks. It is safe and secure. Use the Referral link to claim your free stock when you sign up!.

The Robinhood app makes it easy to trade stocks, crypto and more.


Webull! Receive free stock by signing up using the link: Webull signup.

More Related questions...

What is Java 21 and why is it a significant release? What are Virtual Threads in Java 21 and how do they differ from Platform Threads? How does Pattern Matching for switch work in Java 21? What are Record Patterns in Java 21 and how do they enable deconstruction? What are Sequenced Collections in Java 21? What are sealed classes and interfaces in Java and why are they important for pattern matching? What are Java Records and what do they automatically generate? What are Text Blocks in Java and how do you use them? What is Structured Concurrency in Java 21 and what problem does it solve? What are Scoped Values in Java 21 and how do they differ from ThreadLocal? What is Generational ZGC in Java 21 and why does it improve upon the original ZGC? What important String methods were added from Java 11 through Java 21? What is 'var' in Java and what are its limitations? What are switch expressions in Java and how do they differ from switch statements? How does pattern matching for instanceof work in Java 16+? What Stream API improvements were introduced in Java 9 through Java 21? How has Optional been improved and how should it be used correctly? How does CompletableFuture work in Java and how does it relate to virtual threads? What does the 'volatile' keyword guarantee in Java's memory model? What are the immutable collection factory methods introduced in Java 9? What are functional interfaces in Java and how are lambdas related to them? What are the most important Collectors and how do you write custom ones? What are Unnamed Classes and Instance Main Methods in Java 21 (Preview)? What improvements were made to NullPointerException messages in Java 14? How does type erasure affect instanceof checks with generics in Java? What are the differences between 'synchronized' and ReentrantLock in Java? What are the key classes in the java.time package and when do you use each? What garbage collectors are available in Java 21 and how do you choose between them? What is the Java Platform Module System (JPMS) and when should you use it? What are String Templates in Java 21 (Preview) and how do they improve string interpolation? What are the contracts for equals(), hashCode(), and Comparable in Java? What are the best practices for exception handling in Java? Why is immutability important in Java and how do you implement it correctly? What are default and static methods in Java interfaces? How does HashMap work internally in Java? How do virtual threads compare to reactive programming (Project Reactor / RxJava)? What is the Java 11 HttpClient and how do you use it for HTTP requests? What capabilities do Java enums have beyond simple named constants? What are the java.util.concurrent.atomic classes and how do they work? How does Java Reflection work and what are its performance implications? What are Unnamed Patterns and Variables in Java 21 (Preview) and how do they reduce boilerplate? When should you use StructuredTaskScope instead of CompletableFuture in Java 21? What major APIs were removed between Java 17 and Java 21? What are the most important JVM flags for tuning Java 21 application performance? What are the key steps and pitfalls when migrating an application to Java 21? How do Spring 7 and Spring Boot 4 optimize thread usage compared to older blocking models?
Show more question and Answers...

Spring

Comments & Discussions