In Java, Virtual threads are now supported by the Java Platform. Virtual threads are lightweight threads that greatly minimize the effort required to create, operate, and manage high volumes systems that are concurrent. As a result, they are more efficient and scalable than standard platform threads.
A thread is the smallest processing unit that can be scheduled. It operates concurrently with, and mostly independently of other units of this type. It's an instance of java.lang.Thread.
There are two kinds of threads, platform threads and virtual threads:
- Platform Threads
- Virtual Threads
1. Platform Threads
Operating system (OS) threads are implemented with a platform thread acting as a thin wrapper around them. Java code is executed by a platform thread on its parent OS thread, and the platform thread captures its OS thread for the length of its lifetime.
As a result, there can only be an equal number of OS threads and platform threads.
The operating system usually maintains a large thread stack and additional resources for platform threads. They may be in short supply, but they are suitable for executing many kinds of work.
2. Virtual Threads
A virtual thread is an instance of java.lang.Thread, independent of any OS thread, is used to run programs. The Java runtime suspends the virtual thread until it resumes when the code calls a blocked I/O operation. Virtual threads have a limited call stack and can only execute one HTTP client call or JDBC query. They are suitable for delayed operations, but not for extended CPU-intensive tasks.
Syntax of Virtual Threads:
Thread virtualThread = Thread.ofVirtual().start(() -> {
// Code to be executed by the virtual thread
});
Why Use Virtual Thread?
In your high quantities concurrent applications, use virtual threads if you have many concurrent processes that take a long time to finish. Server applications often handle large numbers of client requests, which requires blocking I/O tasks such as resource access. This makes server applications high-throughput.
Virtual threads do not execute code more quickly than platform threads. Their goal is to provide scale (greater throughput) rather than speed (lower latency).
Advantages of Java Virtual Threads:
There are various advantages to using virtual threads:
- Increases the availability of applications
- Enhances application throughput.
- Reduces the occurrence of 'OutOfMemoryError: Unable to Create New Native Thread'.
- Reduces the amount of memory used by the application
- Enhances code quality
- Platform Threads are completely compatible with them.
How To Create A Virtual Thread?
Platform and virtual thread creation is possible with the Thread and Thread.Builder APIs. The methods to build an ExecutorService that launches a new virtual thread for each operation are also defined in the java.util.concurrent.Executors class.
1. Using the Thread Class and the Thread.Builder Interface to Create a Virtual Thread
Create a version of Thread.Builder using the Thread.ofVirtual() function to build virtual threads.
The following example creates and opens a virtual thread that outputs a message. To wait for the virtual thread to finish its work, it calls the join method. You can see the written message before the main thread ends by doing this.
Thread thread = Thread.ofVirtual().start(() -> System.out.println("Hello"));
thread.join();
You can create threads with standard Thread properties, such as the thread name, using Thread.Builder. While Thread.Builder.OfVirtual creates virtual threads, Thread.Builder.OfPlatform creates platform threads.
The given code starts and opens a virtual thread called "MyThread," prints a message while it's operating, and then uses t.join() to wait for the thread to finish. You can follow these steps to a similar program:
Java
// Java program to demonstrate exchange
// Data between threads using scoped values
import java.util.*;
//Driver class
public class VirtualThreadExample {
// main function
public static void main(String[] args) {
try {
// Initialization of thread
Thread.Builder builder = Thread.ofVirtual().name("GFG Thread");
Runnable task = () -> {
System.out.println("Running thread");
};
Thread t = builder.start(task);
System.out.println("Thread t name: " + t.getName());
// Add a delay to allow the virtual thread to run
// Sleep for 1 second
Thread.sleep(1000);
// Wait for the thread to complete
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Output:
Running thread
Thread t name: GFG Thread
Explanation of the above program:
- Using Thread.ofVirtual().name("MyThread"), we establish a virtual thread.
- Start the thread with a basic Runnable job that outputs "Running thread."
- We use t.getName() to print the thread's name after it has been started.
- To wait for the thread to finish, we use t.join().
- Any InterruptedException that might be generated while the thread is running is identified by us.
This software will launch a virtual thread, carry all the task, print the thread name, and then wait for the thread to terminate.
2. Creating and executing a virtual thread with the Executors.newVirtualThreadPerTaskExecutor() Method
You can separate the creation and management of threads from other software components by using executors.
The Executors.newVirtualThreadPerTaskExecutor() function is used in the example below to build the ExecutorService. To complete the work, a new virtual thread is generated and launched when you use ExecutorService.submit(Runnable). A Future instance is returned by this method. It's important to note that the Future.get() function waits for the thread to complete its task.
The code below code submits a basic task that prints a message and then uses future to wait for the task to finish using an ExecutorService with a virtual thread per task.fetch(). It prints "GeeksForGeeks" to signify that the task has been finished after it is finished.
This Java program represents the behavior in question:
Java
// Java Program for Creating and executing
// Virtual thread with the
// Executors.newVirtualThreadPerTaskExecutor() Method
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class VirtualThreadExecutorExample {
public static void main(String[] args) {
try (ExecutorService myExecutor = Executors.newVirtualThreadPerTaskExecutor()) {
// Submit a task that prints a message
Future<?> future = myExecutor.submit(() -> System.out.println("Running thread"));
// Wait for the task to complete
future.get();
System.out.println("Program Completed !!");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
Output:
Running thread
Program Completed !!
Explanation of the above program:
- We use virtual threads with executors to develop an executor service.virtualThreadPerTaskExecutor() is created.
- We submit a basic task that uses myExecutor to print "Running thread".submit(...) and take note of the Future object that the submission has returned.
- We employ future.get() to pause when the job is finished. This will keep blocking till the job is completed.
- "GeeksForGeeks" is printed to show that the task has been finished after it is finished.
- To handle any exceptions that might arise, we catch ExecutionException and InterruptedException.
Multithreaded Client Server
The example that follows has two classes. A server application called EchoServer listens on a specific port and launches a fresh virtual thread with each new connection. A client application called EchoClient establishes a connection with the server and transmits commands submitted via the command line.
EchoClient connects to EchoServer via establishing a socket. It receives user input via the standard input stream, reads it, and writes the text to the socket to send it to EchoServer.The input is transmitted back to the EchoClient by the EchoServer over the socket. EchoClient receives data from the server and reads and shows it.
- With virtual threads one for each client connection - EchoServer can serve numerous clients at once.
Below is the implementation of the above-mentioned topic:
Java
// Java Program to implement
// Multithreaded Client Server
import java.io.*;
import java.net.*;
//Driver class
public class EchoServer {
//Main method
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.err.println("Usage: java EchoServer <port>");
System.exit(1);
}
int portNumber = Integer.parseInt(args[0]);
try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
System.out.println("EchoServer listening on port " + portNumber);
while (true) {
Socket clientSocket = serverSocket.accept();
// Accept incoming connections
// Start a service thread
Thread.ofVirtual().start(() -> {
try (
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Received: " + inputLine);
out.println("Echo: " + inputLine);
out.flush(); // Explicitly flush the output
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port " + portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
Output:
Usage: java EchoServer <port>
What is the performance impact of Virtual threads?
Platform threads are much heavier than Java virtual threads. More details about Java virtual threads' impact on performance may be found here. However, to describe it briefly:
- Looking for virtual threads will save memory if your program uses a lot of threads or a large stack size.
- By using virtual threads instead of thread pools when your application often generates new threads, you can improve response time.
Similar Reads
Java IO Tutorial Java programming language comes with a variety of APIs that helps the developers to code more efficiently. One of those APIs is Java IO API. Java IO API helps the users to read and write data. In simple words, we can say that the Java IO helps the users to take the input and produce output based on
15+ min read
Java Virtual Machine (JVM) Stack Area The Java Virtual Machine is responsible for running Java applications, and it manages various memory areas, one of which is the Stack Area. In this article, we are going to discuss about JVM Stack Area in depth.JVM Stack AreaIn Java, each thread has its own stack called the Run-Time Stack, created w
5 min read
JRE in Java Java Runtime Environment (JRE) is an open-access software distribution that has a Java class library, specific tools, and a separate JVM. In Java, JRE is one of the interrelated components in the Java Development Kit (JDK). It is the most common environment available on devices for running Java prog
4 min read
Java Tutorial Java is a high-level, object-oriented programming language used to build web apps, mobile applications, and enterprise software systems. It is known for its Write Once, Run Anywhere capability, which means code written in Java can run on any device that supports the Java Virtual Machine (JVM).Java s
10 min read
Java Methods Coding Practice Problems Methods in Java help in structuring code by breaking it into reusable blocks. They improve readability, maintainability, and modularity in programming. This collection of Java method coding practice problems covers functions with return values, functions with arguments, and functions without argumen
1 min read
Difference Between Java Threads and OS Threads In modern computing, multitasking and parallel processing are essential for improving system performance. Two important concepts that enable this are Java Threads and Operating System (OS) Threads. Both play a key role in managing concurrent tasks, but they operate at different levels and interact w
8 min read
How to Call a Method in Java? In Java, calling a method helps us to reuse code and helps everything be organized. Java methods are just a block of code that does a specific task and gives us the result back. In this article, we are going to learn how to call different types of methods in Java with simple examples.What is a Metho
3 min read
Object Model in Java The object model is a system or interface which is basically used to visualize elements in terms of objects in a software application. It is modeled using object-oriented techniques and before any programming or development is done, the object model is used to create a system model or an architectur
8 min read
Java.lang package in Java Java.lang package in JavaProvides classes that are fundamental to the design of the Java programming language. The most important classes are Object, which is the root of the class hierarchy, and Class, instances of which represent classes at run time. Following are the Important Classes in Java.lan
3 min read