Demystifying Virtual Thread Performance: Unveiling The Truth Beyond The Buzz

Demystifying virtual thread performance: unveiling the truth beyond the buzz

The introduction of virtual threads in Java represents a pivotal shift in concurrent programming, aiming to enhance app performance and scalability. This evolution is especially relevant in an era where the right use of hardware assets and responsive app conduct is important. In this blog, we are going to tell you about the Java Virtual Threads, and give you insights into it, and how it improves Java app performances.

What is a Virtual Thread?

Introduced in JDK 19, Java virtual threads provide an easy opportunity for traditional operating system (OS) threads. They intend to address the limitations of conventional thread concurrency models, particularly in I/O-certain eventualities. Traditional Java threads regularly block while watching for I/O operations to finish, leading to inefficiencies in resource usage and alertness responsiveness.

Asynchronous programming paradigms, making use of platform threads provided by the operating system, have been followed to mitigate those inefficiencies. However, such paradigms come with overhead, which helps in consumption and scalability. Virtual threads triumph over those issues by permitting multiple virtual threads to be multiplexed onto a smaller range of platform threads, reducing overhead at the same time as preserving simplicity in programming. Developers can use the virtual threads to handle the concurrent tasks, improve scalability, ease in utilization, and increase efficiency.

When to Use Virtual Threads?

Use virtual threads in high-throughput concurrent applications, specifically people who include an incredible amount of concurrent tasks that spend much of their time waiting. Server programs are examples of high-throughput applications due to the fact they usually take care of many client requests that carry out blockading I/O operations, which include fetching sources.

Virtual Threads do not execute code quickly. Their goal is to offer scale (more throughput) rather than speed (reduced latency).

Also Read:- Accelerate innovation by shifting left finops: part 6 | Optimizing Pgbench for Cockroach DB Part 3 

How do Virtual Threads work?

Java Virtual machines are used to execute the virtual threads in Java and manage the various threads of other operating systems. When you create a virtual thread and submit it for execution, JVM determines the place to map it and makes it available for real execution. 

  • The JVM manages a pool of OS threads and assigns one as a “service thread” to execute the virtual thread’s mission.
  • If the ventures block operations, the virtual threads stop, without affecting the service threads, and enable the other virtual threads to run.
  •   Synchronization between virtual threads is possible through the use of conventional strategies, with the JVM ensuring right coordination.
  • Upon project finishing touch, virtual threads can be recycled for future tasks.
  • If a virtual thread is paused, the JVM can transfer its execution to some other virtual thread or service thread for efficiency.
  • Java’s virtual threads provide lightweight and simple concurrency controlled by the JVM through OS thread mapping and useful resource optimization.

Key Benefits of Virtual Threads

Key Benefits of Virtual Threads

Virtual threads are beneficial in many ways, as they help to reduce overhead, improve scalability, simplify the process, etc.

  • Reduced Overhead: Virtual threads reduce overhead associated with thread control, making an allowance for the creation of thousands and thousands of concurrent duties without depleting system resources.
  • Enhanced Scalability: They enable systems to scale more effectively by supporting a wide variety of concurrent operations, making higher use of multi-middle processors.
  •   Simplified Concurrency: By abstracting away the complexity of conventional thread control, virtual threads make it less difficult to develop and save concurrent programs.

Also Read:- Optimizing Server Management with HAProxy Advanced Health Checks | Build a Philosophy Quote Generator with Vector Search and Astra DB (Part 3)

Performance Applications

I’ve performed the benchmark trying out with the Todo app the usage of Quarkus to enforce 3 styles of offerings consisting of vital (blocking), reactive (non-blocking off), and virtual thread. The Todo app implements the CRUD capability with a relational database (e.g., PostgreSQL) by exposing REST APIs.

Take a look at the following code snippets for every service and the way Quarkus allows developers to put into effect the getAll() approach to retrieve all data from the Todo entity (desk) from the database. You can find solution code in the repository.

  • Imperative (Blocking) Application

In Quarkus systems, you could make techniques and training with @Blocking annotation or non-circulation go-back kind.

  • Virtual Threads Application

It’s quite easy to make a blocking app into a virtual thread software. As you see the code snippets, you need to only add @RunOnVirtualThread to block service, and get AIl( ) technique.

  • Reactive (Non-Blocking) Application

Writing a reactive app should be a large mission for Java builders after they want to apprehend the reactive programming version and the continuation and occasion circulation handler implementation. Quarkus permits developers to put into effect both non-reactive and reactive systems in the equal class because Quarkus is built on reactive engines, including Netty and Vert.X. To make an asynchronous reactive software in Quarkus, you can upload a @NonBlocking annotation or set the go-back type with Uni or Multi in the SmallRye Mutiny task as under the get All() method.

  • Response Time and Throughput

During the performance check, we’ve improved the concurrency ranges from 1200 to 4400 requests according to 2nd. The virtual thread scaled better than other threads, because of its fast response time and throughput. More importantly, it didn’t outperform the reactive service all of the time. When the stage reaches 3500 requests per second, the speed of virtual threads becomes slow.

  • Resource Usage (CPU and RSS)

When you lay out concurrent software regardless of cloud deployment, you or your IT Ops team need to check use of resources and potential with high scalability. The CPU and RSS utilization is a key metric to measure useful resource usage. With that, whilst the concurrency level reached out to 2000 requests per 2nd in CPU and Memory utilization, the virtual threads became swiftly higher than the employee threads.

  • Memory Usage: Container

Container runtimes (e.G., Kubernetes) are necessary to run concurrent systems with high scalability, resiliency, and elasticity on the cloud. The virtual threads had reduced reminiscence use in the restrained box surroundings than the employee thread.


Despite advancements in concurrency abstractions together with coroutines and async/wait for, threads persist as essential components of concurrent programming. They underpin the seamless operation of various software program systems in current times, facilitating parallelism, responsiveness, and efficient aid usage. In the world of AI/ML computations and IoT records handling, we owe it to threads and virtual threads to allow concurrent execution of responsibilities across multi-middle processors, making sure of performance and scalability.

Demystifying Virtual Thread Performance: Unveiling The Truth Beyond The Buzz

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top