Can Java 21’s Virtual Threads Make Thread Pools Obsolete?

The article examines whether Java 21’s cheap virtual threads can replace traditional thread pools, explaining the original purpose of pools, their role as natural throttlers, scenarios where virtual threads excel or fail, and practical guidelines to avoid pitfalls like pinning.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Can Java 21’s Virtual Threads Make Thread Pools Obsolete?

Why Thread Pools Exist

Before Java 21, platform threads mapped directly to OS threads, each requiring about 1 MB of stack and costly user‑kernel switches, so they were cached and reused via thread pools. Virtual threads, implemented in the JVM, cost only a few hundred bytes and are created in microseconds.

Never pool virtual threads. Their creation cost is comparable to a plain new String() object, so pooling would be pointless; let the garbage collector reclaim them.

For I/O‑bound workloads, the traditional reason for thread pools disappears, and the JDK recommends using Executors.newVirtualThreadPerTaskExecutor() to start a new virtual thread per task.

Thread Pools as Natural Rate Limiters

A Tomcat thread pool with 200 core threads caps concurrent request handling at 200, allowing downstream services (e.g., a database pool of 50‑100 connections) to stay within capacity.

If Tomcat is switched to virtual threads, a spike of 50 000 requests could cause the JVM to create 50 000 virtual threads instantly. While the JVM survives, the downstream MySQL, Redis, or microservices cannot handle that load and may crash.

Virtual threads solve the problem of the service itself being blocked on I/O, but they do not address physical bottlenecks of downstream resources. Without a throttling mechanism, overload propagates downstream.

Therefore, even without a thread pool you must introduce explicit limits such as a Semaphore or other rate‑limiting components.

Scenarios Unsuitable for Virtual Threads

Virtual threads are detached from their carrier thread only when they encounter I/O blocking (e.g., HTTP calls, file reads). Pure CPU‑intensive tasks—encryption, image compression, large‑scale sorting—do not block, so a virtual thread occupies its carrier thread continuously.

On an 8‑core machine, eight CPU‑bound virtual threads will consume all carrier threads, leaving tens of thousands of other virtual threads idle and causing a "dead‑lock‑like" state.

For such CPU‑heavy work, use a ForkJoinPool or a properly configured ThreadPoolExecutor with CPU cores + 1 threads, i.e., a platform‑thread pool.

Pinning Pitfall

If a virtual thread blocks inside a synchronized block, it cannot be off‑loaded; the underlying carrier thread becomes "pinned". Legacy libraries that use heavy synchronized sections can therefore pin carrier threads under high load, causing the virtual‑thread pool to collapse.

In such cases, retaining a traditional thread pool remains the safest isolation strategy.

Conclusion

Concurrency programming still demands respect for resource limits and system boundaries. Virtual threads are a powerful tool for I/O‑bound workloads, but for stability and downstream protection, thread pools—or explicit throttling—remain indispensable.

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.

JavaConcurrencythread-poolvirtual-threadsjava-21
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

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.