Java Introduces Preview Version of Virtual Threading, Significantly Improves Application Throughput

OpenJDK's JEP 425: Virtual Threads (Preview) Feature Proposal says: The Java platform will introduce virtual threads. Virtual threads are lightweight threads that can significantly reduce the workload of writing, maintaining, and observing high-throughput concurrent applications.

Java developers have always relied on threads as the building blocks of concurrent server applications, where statements in each method are executed within a thread, and each thread provides a stack to store local variables and coordinate method calls, as well as context capture in case of errors. Threads are Java's unit of concurrency and the core foundation of Java tools: the debugger steps through the statements in the thread's methods, and the profiler visualizes the behavior of multiple threads.

Currently, the JDK implements its platform threads as wrappers for operating system (OS) threads, each instance in the JDK is a platform thread, the platform thread runs Java code on the underlying OS thread, and runs Java code for the entire life cycle of the code Capture OS threads. The number of platform threads is limited by the number of OS threads, and OS threads are expensive and cannot take up too much. As a result, the current JDK's approach to threading limits the throughput of its applications well below what the hardware supports.

About virtual threads

A virtual thread java.lang.Threadis one that runs Java code on the underlying operating system thread (OS thread), but does not capture instances of the OS thread for the entire lifetime of the code. This means that many virtual threads can run Java code on the same OS thread, effectively sharing it.

Virtual threads are a lightweight implementation of threads provided by the JDK rather than the operating system, and are a form of user-mode threading . User-mode threads were called "green threads" in early versions of Java , when the concept of operating system threads was not mature and popular enough, and all green threads in Java shared an OS thread (M:1 scheduling), with the thread concept With the development of , the green thread is finally surpassed by the current platform thread and implemented as a wrapper of the OS thread (1:1 scheduling), while the newly introduced virtual thread adopts M:N scheduling, in which a large number (M) of virtual threads are scheduled as Runs on a smaller number (N) of OS threads.

higher throughput

Developers can choose to use virtual threads or platform threads, but virtual threads perform better in high-throughput server applications. For example, the following code that sleeps for one second creates a large number of virtual threads. The program first obtains an  ExecutorService , which creates a new virtual thread for each submitted task, then submits 10,000 tasks and waits for all tasks to complete:

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 10_000).forEach(i -> {
        executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1));
            return i;
        });
    });
}  // executor.close() is called implicitly, and waits

Modern hardware can easily support 10,000 virtual threads running such code simultaneously. If the program uses an ExecutorService that creates a new platform thread for each task, e.g. Executors.newCachedThreadPool() , then it will try to create 10,000 platform threads, which means 10,000 OS threads, and the program will not work on most operations The system will crash. Or the program uses an ExecutorService that obtains platform threads from the pool, such as Executors.newFixedThreadPool(200), which is not much better. ExecutorService will create 200 platform threads for these 10,000 tasks to share, the tasks will run sequentially instead of simultaneously, and the program will take a long time to finish.

For the above program, a pool with 200 platform threads can only achieve a throughput of 200 tasks per second, while virtual threads can achieve a throughput of about 10,000 tasks per second (after sufficient warm-up). Also, if you change 10000 to 1,000,000 in the example program, the program will submit 1,000,000 tasks, create 1,000,000 virtual threads running concurrently, and (after sufficient warm-up) achieve a throughput of about 1,000,000 tasks/second.

In summary, virtual threads are not faster threads - they run code no faster than platform threads. They exist to provide scale (higher throughput), not speed (lower latency).

How to enable virtual threads?

Virtual threads are currently widely used in other multithreaded languages ​​(such as goroutines in Go and processes in Erlang, and are also a stable feature in C++), but are still a preview API in Java and disabled by default. To try this feature on JDK XX, the preview API must be enabled by:

  • Compile the program with javac --release XX --enable-preview Main.java and run it with java --enable-preview Main
  • When using the source code launcher, run the program with java --release XX --enable-preview Main.java
  • When using jshell, start with jshell --enable-preview

More information about virtual threads can be found in OpenJDK's  JDK Issue-8277131  . The proposal was created on 2021/11/15 and is currently in the first phase of the JEP process, and it will take some time before a stable release.

Guess you like

Origin www.oschina.net/news/190175/java-virtual-threads-preview