DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • A Beginner's Guide to Back-End Development
  • Java and Low Latency
  • All You Need To Know About Garbage Collection in Java
  • Java Concurrency Evolution

Trending

  • Endpoint Security Controls: Designing a Secure Endpoint Architecture, Part 2
  • Memory-Optimized Tables: Implementation Strategies for SQL Server
  • Designing AI Multi-Agent Systems in Java
  • Web Crawling for RAG With Crawl4AI
  1. DZone
  2. Coding
  3. Java
  4. Unleashing the Power of Lightweight Concurrency: A Comprehensive Guide to Java Virtual Threads (Part 1)

Unleashing the Power of Lightweight Concurrency: A Comprehensive Guide to Java Virtual Threads (Part 1)

In this article, we'll cover the basics of Java Virtual Threads, how they work, why they are beneficial for developers, and how they overcome limitations.

By 
A N M Bazlur Rahman user avatar
A N M Bazlur Rahman
DZone Core CORE ·
May. 10, 23 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
5.1K Views

Join the DZone community and get the full member experience.

Join For Free

Java Virtual Threads, also known as lightweight threads, is an exciting new feature introduced in Project Loom.

Virtual threads aim to simplify concurrent programming in Java by providing an efficient and easy-to-use concurrency model.

In this article, we'll cover the basics of Java Virtual Threads, how they work, why they are beneficial for developers, and how they overcome the limitations of traditional Java threads.

What Are Virtual Threads?

Java is made of threads. When we run a Java program, its main method is invoked as the first call frame of the main thread created by the Java launcher. It gives us many things: sequential control flow, local variables, exception handling, single-step debugging, and profiling.

It makes our lives easier by providing exception handling with informative stack traces and serviceability tools that let us observe what's happening in each thread, providing remote debugging and creating an illusion of sequentiality that makes our code easier to reason.

Most JVM implementations today implement Java threads as thin wrappers around operating system threads. We call these heavyweight, OS-managed threads "platform threads." Operating systems typically allocate thread stacks as monolithic memory blocks at thread creation time that cannot be resized later-generally 2 MB (on Linux). One million threads would require two terabytes of memory! It essentially means that we can't have a lot of them.

In a server application, a thread is assigned to each incoming request. This approach scales well for moderate-scale applications, e.g., 1,000 concurrent requests, but cannot survive 1M concurrent requests, even though we have adequate CPU capacity and IO bandwidth.

Virtual threads are an alternative implementation of Java threads that store their stack frames in Java's garbage-collected heap rather than in monolithic blocks of memory allocated by the OS. It starts out at only a few hundred bytes and expands and shrinks automatically.

The operating system only knows about platform threads, which remain in the scheduling unit. To run code in a virtual thread, the Java runtime arranges for it to run by mounting it on a traditional thread called a "carrier thread."

Virtual threads

When code running in a virtual thread would otherwise block for IO, locking, or other resource availability, it can be unmounted from the carrier thread, and any modified stack frames copied back to the heap, which frees the carrier thread to run something else.

With this virtual thread, we get all the benefits traditional threads have, plus it is cheap, lightweight, and virtually free. Moreover, we can create many of them.

Consider the following example:

Java
 
try (var executor = Executors.newVirtualThreadPerTaskExecutor()){
  IntStream.range(0, 10_000).forEach(i -> {
  executor.submit(() -> {
    Thread.sleep(Duration.ofSeconds(1));
    return i;
  });
});
}


The JDK can now run up to 10,000 concurrent virtual threads on a small number of operating system (OS) threads, as little as one, to execute the simple code above that involves sleeping for one second.

Why Use Virtual Threads?

  1. Scalability: Since a large number of virtual threads are easy to create, the thread-per-request programming style alleviates this scalability bottleneck. In other words, high throughput is very simple to achieve.
  2. Simplified Concurrency: Virtual threads make concurrent programming in Java easier by allowing developers to write code using familiar synchronous APIs. This eliminates the need for complex asynchronous programming patterns, such as callbacks, promises, or reactive programming, which can be difficult to understand and maintain.
  3. Improved Resource Utilization: Virtual threads help maximize resource utilization by ensuring that kernel threads are not idle while waiting for I/O operations to complete. By efficiently managing the execution of virtual threads, the Java runtime can keep kernel threads busy, resulting in better overall performance.

Getting Started With Virtual Threads

Project Loom is still an experimental feature and is not available in stable Java releases. JDK 21, which is still not released, is expected to include virtual threads.

To manage your JDK installations, we recommend using SDKMAN, a versatile tool that simplifies the process of installing, switching, and managing multiple JDK versions. You can find more information about SDKMAN and installation instructions on their official website.

Once you have SDKMAN installed, you can list available JDK versions, including early access builds, and install the desired version:

Shell
 
$ sdk list java 
$ sdk install java <version>


Replace <version> with the specific version, you'd like to install, such as the early access build of JDK 21 that includes virtual thread support.

Once you have downloaded JDK 21, you can create virtual threads in three ways:

Using the Thread Factory Method

Java
 
Thread.startVirtualThread(() -> 
   System.out.println("Hello world!");
});


You don't need to start the thread; it automatically starts and executes.

Note that virtual threads are always daemon threads. So make sure you wait on the main thread. Otherwise, you may not see the output.

Java
 
var thread = Thread.startVirtualThread(() -> 
   System.out.println("Hello world!");
});

thread.join();


Using the Builder Method

Like the factory method, you can use the builder method, which is much more convenient as you can create started or unstarted threads.

Java
var started =Thread.ofVirtual().start(() -> 
   System.out.println("Hello world!");
});


To create an unstarted thread, you can use the following:

Java
 
var unstarted = Thread.ofVirtual().unstarted(() -> 
   System.out.println("Hello world!");
});


Using the Executors

If we want to move away from our existing code, which is heavily dependent on executors, one new method that is just one line long and uses virtual threads has been added.

Java
 
var executorService = Executors.newVirtualThreadPerTaskExecutor()

executorService.submit(() -> {
   System.out.println("Hello world!");

});


Conclusion

Java Virtual Threads provide a powerful and efficient concurrency model for modern applications. By simplifying concurrent programming and allowing for better resource utilization, virtual threads have the potential to revolutionize the way developers write concurrent code in Java.

As Java continues to evolve and innovate, staying informed about cutting-edge features like virtual threads is crucial for developers seeking to stay ahead of the curve and harness the full potential of the Java ecosystem.

If you found this article to be informative and engaging, please consider giving it a thumbs up and sharing it with your colleagues and friends. Thanks for your support!

Note: In the next article, we will delve deeper into the implementation and explain the internals of the virtual threads introduced in this article. Stay tuned.

Java virtual machine Java (programming language) operating system

Published at DZone with permission of A N M Bazlur Rahman, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • A Beginner's Guide to Back-End Development
  • Java and Low Latency
  • All You Need To Know About Garbage Collection in Java
  • Java Concurrency Evolution

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!