What are Virtual threads
Before we even look into definition of Virtual threads, lets clarify some terminology which will help us understanding Virtual threads better.
Platform Thread
The term 'Platform Thread' is used in two contexts:
Traditional Java Thread
- For non Virtual Thread, the thread which we had/have before Virtual thread, the traditional OS(Operating System) backed Java thread and scheduled by OS. Platform thread run Java code on its underlying OS thread and captures OS thread for its entire life cycle which means the captured OS thread can not be used by any other request/task because of which the number of available platform threads is limited to the number of available OS threads. Note that these traditional Platform threads are not Carrier threads, as their purpose is not to run Virtual threads.
- For the threads on which Virtual threads are mounted, also known as Carrier threads.
Carrier Thread
They are special Platform threads created and managed by JVM to run Virtual threads.
Platform threads(Traditional or Carrier) are relatively heavy weight compared to Virtual thread. A stack for Platform thread takes around 1 MB of memory(we can configure it with JVM parameter -Xss)
Now let us understand what Virtual threads are.
Virtual Thread
They are relatively light weight threads with size of around 2-10 KB(can grow dynamically) and are managed entirely by the JVM rather than the operating system. They are not directly mapped 1:1 to OS threads. Instead, the JVM schedules many virtual threads onto a smaller pool of Platform threads called Carrier threads. This makes them memory-efficient and highly scalable. We will look into scalability in some time soon in one of next few paragraphs.
Remember that all Carrier threads are Platform threads, but not all Platform threads are Carrier threads.
How to create Platform Threads V/s Virtual Threads V/s Carrier Threads
Platform Threads:
Creating a Thread with java.lang.Thread class or using ExecutorService give us platform thread, each of which is backed 1:1 by an OS thread. Actually the term ‘Platform thread’ was introduced in JDK 19 when Virtual Thread was added as a preview feature, to distinguish these threads from newly introduced Virtual threads, but as mentioned before that these Platform threads are not the Carrier threads.
So using old Thread API, all following returns Platform thread which is mapped 1:1 to OS thread:
1) Using java.lang.Thread class to create Thread
Thread t = new Thread(() -> {
System.out.println("Running on: " + Thread.currentThread().getName());
});
2) Using ExecutorService to create Thread Pool will create pool of Platform Threads
Executors.newFixedThreadPool(8)
Executors.newCachedThreadPool()
Executors.newSingleThreadExecutor()
Executors.scheduledThreadPool()
3) Using CompletableFuture
CompletableFuture.supplyAsync(dbCall(), executor)
4) Using new Thread.Builder API
Thread.ofPlatform().start(() -> System.out.println("Platform Thread"));
Virtual Threads:
And here is how we can create Virtual threads :
1. Using Thread.Builder API
Thread thread = Thread.ofVirtual().start(() -> System.out.println("Hello"));
2. Using ExecutorService
Executors lets us separate thread creation and management from the rest of our application.
3. Using Structured concurrency
Why Virtual Threads ? What problem they solve ?
Java server side applications typically follow thread-per-request model which means for each incoming HTTP request to the server, server will assign a thread from its thread pool to handle the request. These were Platform threads with 1:1 mapping to OS threads, meaning each Java thread directly occupied an underlying OS thread while processing the request.
However, this model had following limitations :
- Blocking operations are expensive because the OS thread remains blocked and unavailable for other requests. So when a request makes an I/O, DB, other network call, OS thread stays idle while waiting and this limits scalability because the server can only handle a few thousand concurrent requests before running out of threads or memory.
To be continued....