Before delving into this blog, you must have basic knowledge of the following topics:
- Java Threads
- Java Concurrency
Project Loom is an experimental project undertaken by the Java Language Group at Oracle Corporation to enhance the concurrency model of the Java Virtual Machine (JVM). There are many features/enhancements introduced as a part of Project Loom. Today, we will look at one of those features (Virtual Threads) which provides a significant improvement over the older version of Java.
Virtual Threads are a key feature of Project Loom, and it provides a significant improvement over Platform Threads. To begin with, let’s first try to understand what a Platform Thread and a Virtual Thread are.
Platform Threads: A thread is a unit of execution that is created/managed by the OS. Now, when we use a platform thread in Java i.e. the regular Thread class, each platform thread is mapped to an OS Thread and is managed by the OS. Creating a platform thread involves a system call which is a costly operation. They are created and controlled by the OS kernel and are scheduled and executed by the underlying hardware.
Virtual threads, also known as lightweight threads or fibers, are user-space threads managed by a runtime library or in other words the JVM. They are not directly managed by the operating system (OS). Each virtual thread is a unit of execution that can be scheduled and managed by the JVM independently of OS Threads (Platform Threads).
Now that we know about both types of threads let’s ponder into some of the differences between them. We will also look at how Virtual Threads can be utilized as an improvement over the traditional platform threads. We will understand the differences based on some properties of Virtual Threads:
Platform threads are directly linked to OS threads which means they are resource heavy. Creating, destroying, and switching between threads can be a costly operation.
Virtual Threads are independent of OS Threads. They are much lighter than Platform threads in terms of memory usage and context-switching overhead. This allows for creating a lot higher number of threads and also managing those efficiently as they are tied to the JVM and not directly with the OS.
Platform Threads can be scaled at max equal to the number of OS Threads i.e. the max number of threads supported by the processor. So, the scalability of Platform Threads is very limited and we cannot create a large number of platform threads without going out of memory.
Virtual threads can be virtually scaled significantly higher as each virtual thread is not linked to an OS Thread. The JVM can manage and create multiple virtual threads which can be assigned to a single OS Thread. Hence, the number of virtual threads is not limited by the system configuration. This enables us to create an insane number of virtual threads without ever going out of memory. Just try this on your machine you might be amazed by the number(I was).
Platform Thread is managed and scheduled by the operating system. It has its own stack, registers, and other resources. This makes them heavyweight and expensive to create and maintain.
Virtual Threads are scheduled and managed by the JVM, which can improve performance and reduce the overhead of thread management. As virtual threads are lightweight, they can be created and destroyed more quickly than platform threads. Hence, they are significantly more efficient than platform threads as they are way less resource expensive.
Virtual threads typically follow a cooperative multitasking or non-preemptive model. They are scheduled and yield control voluntarily, allowing other virtual threads to execute. This cooperative nature allows for high concurrency and efficient use of system resources. The scheduling of virtual threads is typically managed by the runtime library or language runtime. It may use techniques like work-stealing or event loops to efficiently allocate CPU time among threads. Scheduling decisions can be made based on factors like thread priority, fairness, or specific scheduling policies implemented by the library.
Platform threads generally follow a preemptive multitasking model. The operating system scheduler determines when to preempt a thread and switch to another. Preemption can occur at any point during the thread’s execution, based on the scheduling algorithm and priorities set by the OS. Platform threads provide true parallelism by utilizing multiple CPU cores. The scheduling of platform threads is managed by the operating system’s scheduler. The scheduler decides when to allocate CPU time to each thread based on factors like thread priority, thread affinity, and scheduling policies defined by the OS. The scheduler takes into account the available CPU resources, fairness, and various optimization strategies.
Based on the above points it seems like Virtual Threads are an obvious improvement over Platform Threads. But is it always the case? Let’s find out by exploring the use cases for each of them:
Virtual Threads and Platform Threads have different characteristics and usage scenarios, which make them suitable for different use cases. Here are some examples of when each type of thread might be more appropriate:
Use Cases for Virtual Threads (Project Loom):
- Highly Concurrent Applications: Virtual threads are useful in scenarios where high concurrency is required. For example, server applications that handle a large number of concurrent connections or event-driven systems. Virtual threads’ lightweight nature and cooperative scheduling enable efficient management while dealing with a large number of concurrent tasks.
- Microservices and Serverless Architectures: In distributed systems built on microservices or serverless architectures, virtual threads can be useful for achieving efficient resource utilization and scalability. They can handle individual requests or tasks within a service without the need for dedicated platform threads. This allows for higher throughput and better responsiveness.
- Reactive Programming: Virtual threads can be used effectively in reactive programming frameworks or libraries that rely on event-driven, non-blocking concurrency models. They can help simplify the development of reactive systems by providing a more sequential and intuitive programming model, while still achieving high concurrency and responsiveness.
- Asynchronous I/O: Virtual threads are well-suited for asynchronous programming models where non-blocking I/O operations are performed. By utilizing virtual threads, developers can write code that executes synchronously while achieving the benefits of asynchronous I/O, such as improved responsiveness and resource utilization.
Use Cases for Platform Threads:
- Operating System Interactions: When interacting with low-level operating system functionalities or APIs that require platform thread management. For example, system calls or hardware device access, and platform threads are necessary. The operating system’s thread management and scheduling mechanisms ensure proper coordination and execution of these interactions.
- CPU-Intensive Processing: Platform threads are better suited for CPU-bound tasks that require true parallelism. For example, intensive computational algorithms or simulations. Since platform threads are managed by the operating system and can be distributed across multiple CPU cores, they can leverage the hardware capabilities for parallel execution.
- Legacy Code and Libraries: Existing code or third-party libraries that are not designed to work with virtual threads may require the use of platform threads. If the code relies heavily on traditional thread management primitives or relies on the operating system’s thread model, transitioning to virtual threads might be more complex or not feasible.
- Portability across Languages and Platforms: Platform threads provide a more standardized and portable approach compared to virtual threads, which are often language-specific or tied to specific runtime environments. If portability across different programming languages or platforms is a requirement, using platform threads based on industry-standard APIs like POSIX threads may be a better choice.
In this blog, we learned about platform threads and virtual threads, how they differ from each other, and how virtual thread is an improvement over the existing threads in Java. In the upcoming blogs, we will also explore how to implement virtual threads and so on. So stay tuned on Nashtech Blogs.