Exploring Virtual Thread Behavior with Concurrent HTTP Calls
Understanding how virtual threads, introduced in Java 16, interact with underlying OS threads is crucial for optimizing I/O bound tasks. This code snippet demonstrates creating two virtual threads that perform calculations and make slow HTTP calls. Here, we aim to analyze the internal behavior of the JVM and OS threads during execution
Thread thread = Thread.ofVirtual().start(() -> {
int a = 2+3; slowHttpCall();int c = a+5;Sysout(c);
});
Thread.ofVirtual().start(() -> {
int x = 2+3; slowHttpCall();int y = x+5;Sysout(y);
});
Code Analysis:
The code creates two virtual threads using Thread.ofVirtual().start()
. Each thread performs the following actions:
- Calculates
2 + 3
and stores the result in a variable. - Makes a slow
httpCall()
(assumed to be an I/O operation). - Calculates another expression (
a + 5
orx + 5
) and stores the result. - Prints the final result using
System.out.println(c)
orSystem.out.println(y)
.
Virtual Threads and OS Threads:
- JVM Creates Virtual Threads: The JVM creates two virtual threads,
thread1
andthread2
, to represent the code you provided. - Mapping to OS Thread: The JVM might initially map both virtual threads to the same underlying OS thread provided by the operating system.
Execution Flow (Possible Scenario):
2 + 3
Calculation: The OS thread, associated with both virtual threads, executes2 + 3
forthread1
and stores the result ina
.httpCall()
Initiation: Whenthread1
encountersslowHttpCall()
, the JVM initiates the call but doesn’t necessarily block the OS thread.- Potential Thread Switch: Depending on the JVM’s scheduling and the availability of other runnable virtual threads, the JVM might switch the OS thread to
thread2
. 2 + 3
Calculation (thread2): The OS thread now executes2 + 3
forthread2
and stores the result inx
.httpCall()
Initiation (thread2): Whenthread2
encountersslowHttpCall()
, the JVM initiates the call forthread2
as well.
Here’s where the exact behavior can vary depending on the specific JVM implementation and OS interaction:
- OS Thread Management: The JVM might keep the OS thread associated with either
thread1
orthread2
(or potentially switch it back tothread1
) while thehttpCall()
operations are ongoing. This decision depends on factors like expected call duration and the availability of other virtual threads. - I/O Handling: The operating system and the JVM work together to handle the
httpCall()
operations asynchronously. The OS thread might not be completely blocked, and the JVM might be notified when the calls finish.
After the httpCall()
s complete (assumed to be slow):
- The JVM resumes the appropriate virtual thread (
thread1
orthread2
) based on the completion order of the calls. - The resumed virtual thread completes its remaining calculations (
a + 5
orx + 5
) and prints the result usingSystem.out.println()
.
Important Notes:
- The exact number of OS threads used and the switching behavior can vary depending on the JVM implementation and the operating system.
- The code snippet doesn’t handle potential errors or timeouts during the
httpCall()
operations.
In essence, virtual threads provide an abstraction layer. You write code using virtual threads, and the JVM manages their execution efficiently on underlying OS threads. This allows the program to potentially avoid blocking the CPU core while waiting for I/O operations to complete.
when jvm initiates slowhttpcall of thread1 and switches OS thread to virtual thread 2…wont it need a thread for slowhttpcall also?
You’re absolutely right! When the JVM initiates the slowHttpCall()
of thread1
and potentially switches the OS thread to thread2
, it doesn’t necessarily need a separate thread just for the slowHttpCall()
. Here’s why:
Asynchronous I/O and Non-Blocking Calls:
- The
slowHttpCall()
is assumed to be an I/O operation. Modern JVMs typically leverage asynchronous I/O or non-blocking I/O techniques to handle such operations efficiently. - In these approaches, the thread initiating the I/O call (in this case,
thread1
) doesn’t block and wait for the call to complete. - Instead, the JVM registers the call with the operating system and continues execution with other tasks (potentially switching the OS thread to
thread2
).
OS and JVM Cooperation:
- The operating system manages the underlying network communication for the
slowHttpCall()
. - Once the
slowHttpCall()
finishes, the operating system notifies the JVM through an event or callback mechanism.
JVM Resumes the Right Thread:
- When the JVM receives the notification for
thread1
‘sslowHttpCall()
completion, it can resumethread1
on the available OS thread (which might be the same thread used bythread2
earlier).
Benefits:
- This approach avoids blocking the CPU core while waiting for the
slowHttpCall()
to complete. - The JVM can utilize the OS thread for other virtual threads like
thread2
while waiting for the I/O operation.