Recommended Free Tools
Java virtual threads became a permanent Java feature in JDK 21, released on 19 September 2023. They let applications run many lightweight, JDK-managed threads over a smaller number of operating-system threads, making thread-per-task code more scalable when tasks spend much of their time waiting. The road to that release ran through two preview versions because Loom had to change how Java schedules threads without discarding the familiar java.lang.Thread programming model.
What Project Loom set out to change
Project Loom was an OpenJDK effort to address a limit in the traditional thread-per-request approach: a Java platform thread generally occupies an operating-system (OS) thread for its lifetime. OS threads are comparatively costly, so applications often use small platform-thread pools. That controls resource use, but it can also limit how many tasks wait concurrently.
Loom’s goal was to preserve the straightforward flow of ordinary thread-based code while changing the implementation and scheduling costs. Instead of requiring a new callback-oriented programming model, it introduced virtual threads: instances of java.lang.Thread that the JDK schedules rather than mapping one-to-one to OS threads.
When virtual threads moved from preview to stable
| Release | Milestone | What it meant |
|---|---|---|
| JDK 19 (2022) | JEP 425 | First preview of virtual threads, inviting developers to try the feature while its design was still subject to change. |
| JDK 20 (2023) | JEP 436 | Second preview, giving the team another cycle to gather feedback on the API and runtime behavior. |
| JDK 21 (19 September 2023) | JEP 444 | Virtual threads were finalized as a permanent Java platform feature. |
“Stable” here means finalized in the Java platform, not a promise that every application or library benefits equally. JDK 21 is the release in which developers can use virtual threads without enabling a preview feature.
How a virtual thread runs
Virtual threads use M:N scheduling: many virtual threads (M) are multiplexed over a smaller pool of OS threads known as carrier threads (N). A virtual thread occupies a carrier while executing Java code. When it performs a supported blocking operation in a java.* API, it can suspend and unmount from that carrier, leaving the carrier available to run other work. When the virtual thread is ready to continue, the JDK schedules it again.
A platform thread, by contrast, generally holds its OS thread for its lifetime. Virtual threads keep the familiar thread abstraction, including stack traces, interruption, and thread-local support, while changing how execution is scheduled underneath. That compatibility is central to Loom’s approach: existing sequential code can often be used with relatively few source changes rather than being rewritten around callbacks.
Rank #2
Why it took two previews to finalize
Changing the cost of a thread is not just a scheduler problem. Java applications and tools rely on threads for control flow, exception propagation, debugging, profiling, interruption, and per-thread state. A design that scaled but broke those expectations would impose a broad migration on developers.
The preview cycles gave the JDK team time to refine API and runtime behavior in response to developer feedback before declaring the feature permanent. In the final design, virtual threads always support thread-local variables. Threads created through the direct Thread.Builder API are monitored by default for their lifetime and appear in virtual-thread-aware observability tooling.
Free tools Windows power users keep installed
One-click scans. No signup required.
Where virtual threads help—and where they do not
The strongest fit is a workload with many concurrent tasks that spend substantial time waiting for network, database, or other blocking I/O. When waiting tasks can release their carriers, an application can keep the readable thread-per-task style without dedicating one OS thread to every waiting task.
Virtual threads are not faster threads. They do not make an individual calculation run faster or increase the number of processor cores available for CPU work. Their benefit is scale and potential throughput for waiting-heavy workloads, not lower execution time for each task.
Rank #4
| Workload or constraint | What virtual threads change | Practical implication |
|---|---|---|
| Many tasks waiting on supported blocking I/O | Suspended virtual threads can release their carriers. | More concurrent tasks can share a smaller set of OS threads. |
| CPU-bound computation | More threads do not create more processor capacity. | Keep CPU throughput bounded by the available cores; additional concurrency is not a speed boost. |
| Scarce downstream capacity, such as database connections | Virtual threads do not increase the capacity of that resource. | Retain connection limits, rate limits, and other controls appropriate to the downstream system. |
| Expensive resource created for every task | Lightweight threads do not make the resource itself cheap. | Avoid coupling one costly resource to every virtual thread if that can degrade performance. |
JEP 444 illustrates the distinction with about 1,000,000 tasks per second for 1,000,000 sleeping tasks after sufficient warmup. That is an illustrative JEP example, not a general benchmark or a forecast for application throughput; replacing the sleep with a second of computation would not make the work faster through added threads.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Should you replace a thread pool?
For independent, blocking tasks, the Java 21 API provides Executors.newVirtualThreadPerTaskExecutor(). The intended lifecycle is generally one new virtual thread per task, not a pool of reusable virtual threads. Pooling virtual threads to conserve threads works against their purpose; keep pools where they bound a scarce resource or limit CPU work.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchBest Value
A minimal Java 21 example looks like this:
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> handleRequest());
}
This example submits one task; real applications must still manage task results, failures, cancellation, and downstream resource limits according to their needs. The executor changes the execution model, not the requirements of the work.
A practical adoption sequence
- Choose a waiting-heavy path. Start with request or task orchestration that spends meaningful time in blocking I/O, rather than expecting CPU-intensive work to become faster.
- Use per-task virtual threads. In JDK 21, try
Executors.newVirtualThreadPerTaskExecutor()or the thread-builder APIs where appropriate. - Preserve external capacity controls. Keep database connection bounds, service rate limits, and other limits tied to resources that remain scarce.
- Measure representative load. Compare throughput, latency, memory use, downstream saturation, and pinning behavior under realistic concurrency; results depend on the application and its dependencies.
What to watch in production
More available threads do not mean every blocking path behaves identically. Pay attention to synchronized sections, native calls, and libraries whose blocking behavior may not be virtual-thread-friendly; these can affect whether a carrier is available to do other work. Observe the application under representative load rather than assuming that changing the executor alone guarantees a gain.
Operational visibility also matters when thread counts grow. Virtual threads remain ordinary java.lang.Thread instances from an application’s perspective, and the JDK’s virtual-thread-aware observability support helps make them inspectable. Treat debugging and monitoring as part of the migration, alongside throughput and resource measurements.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →

