New Java release includes virtual threads, structured concurrency, and more
Another six months have passed; and with predictable reliability, we have another release of the core Java platform, JDK 19.
This is classified as a Feature release rather than one with Long Term Support (LTS); the last LTS release was JDK 17. However, this does not mean you should ignore this one. Although it is unlikely you will use this release in production, it is important to test your applications with it to prepare for the next LTS version, which will be JDK 21 since the OpenJDK community moved to two years between LTS versions (instead of three).
Azul provides two distributions of JDK 19. The first is Azul Platform Core, which is built directly from the unmodified OpenJDK source code. This is available as a free download here. The second is Azul Platform Prime, which is based on OpenJDK 19 but with enhancements to deliver better performance. It should be noted that, although Azul Platform Core for JDK 19 is now a released version (classified as GA), the Azul Platform Prime is still in preview form (there are more details closer to the end of this article).
You can download and freely use the Azul Platform Prime JDK 19 preview for development and testing to explore the newest JDK features together with the world’s fastest JVM.
Preview features and incubator modules
Technically, JDK 19 contains no new major features, as defined by individual Java Enhancement Proposals (JEPs). How can that be, given there are seven JEPs listed for inclusion? Six of those JEPs are either preview features or incubator modules. The seventh is a new port of OpenJDK to Linux on RISC-V, which doesn’t seem like a feature. Still, there are some exciting changes.
A preview feature is a new feature of the Java language, Java Virtual Machine, or Java SE API that is fully specified, fully implemented, and yet impermanent. It is available in a JDK feature release to provoke developer feedback based on real world use; this may lead to it becoming permanent in a future Java SE Platform.
An incubator module is a means of putting non-final APIs and non-final tools in the hands of developers, while the APIs/tools progress towards either finalization or removal in a future release.
Exciting new features in JDK 19
The most significant are JEP 425: Virtual Threads and JEP 428: Structured Concurrency. Both features are part of Project Loom, which has been in development for over four years and is finally included in the JDK for evaluation and to solicit feedback.
JEP 425: Virtual Threads (preview)
JEP 425 has three goals:
- Enable server applications written in the simple thread-per-request style to scale with near-optimal hardware utilization
- Enable existing code that uses the
java.lang.Thread
API to adopt virtual threads with minimal change - Enable easy troubleshooting, debugging, and profiling of virtual threads with existing JDK tools
Before virtual threads, each thread in a Java application is mapped directly to an operating system (OS) thread. This makes sense because the JVM does not need to be concerned with things like direct scheduling and context switching of the threads. However, it does become an issue for certain common types of applications. Take the example of a web server that handles connections that do nothing for long periods while a user decides what to do next. In this case, the Java thread blocks, but this also prevents the OS thread from doing anything. When the number of simultaneous connections grows to a very high number, we can exhaust the available OS threads, even though many of these threads are doing nothing.
Virtual threads solve this by having multiple Java threads map to a single OS thread. As a result, OS threads can now be used efficiently to service Java threads that need to do work, and an application can support literally millions of simultaneous connections. (This is just one example of how virtual threads can be used; there are plenty of others).
JEP 428: Structured Concurrency (preview)
JEP 428 has two goals:
- Improve the maintainability, reliability, and observability of multithreaded code.
- Promote a style of concurrent programming which can eliminate common risks arising from cancellation and shutdown, such as thread leaks and cancellation delays.
Structured Concurrency is also part of Project Loom. It aims to simplify Java concurrent programs by treating multiple tasks running in different threads (forked from the same parent thread) as a single unit of work. JEP 428 provides a mechanism to split a task into concurrent subtasks, which all return to the same place: the task’s code block. An obvious question related to this is how does this differ from the existing ForkJoinPool functionality? ForkJoinPool is designed to handle compute-intensive tasks, whereas the structured concurrency API is for I/O-intensive tasks.
JEP 405: Record Patterns (preview)
JEP 405 has two goals:
- Extend pattern matching to express more sophisticated, composable data queries.
- Do not change the syntax or semantics of type patterns.
JDK 19 continues the theme of language-level pattern matching from recent releases. JEP 405 introduces Record Patterns, which builds on Pattern Matching for instanceof (JEP 394), introduced in JDK 14. In addition to matching a specified type pattern, the record is deconstructed into its variables. Here’s a simple example.
if (o instance record Point (x,y)) {
System.out.printIn("point [" + x + "," + y + "]");
}
We match against a type pattern that is the record definition and can directly access the state within the record.
This eliminates the need to extract the values of x and y from the record via accessor methods. In keeping with the goals of Project Amber, this reduces the amount of ceremony (or boilerplate code) without sacrificing any readability.
JEP 424: Foreign Function and Memory APIs (preview)
JEP has four goals:
- Ease of use — Replace the Java Native Interface (JNI) with a superior, pure-Java development model.
- Performance — Provide performance that is comparable to, if not better than, existing APIs such as JNI and
sun.misc.Unsafe
. - Generality — Provide ways to operate on different kinds of foreign memory (e.g., native memory, persistent memory, and managed heap memory) and, over time, to accommodate other platforms (e.g., 32-bit x86) and foreign functions written in languages other than C (e.g., C++, Fortran).
- Safety — Allow programs to perform unsafe operations on foreign memory, but warn users about such operations by default.
Turning to new core libraries, JDK 19 contains further work on the Foreign Function and Memory APIs (JEP 424). These are part of Project Panama, a replacement for the Java Native Interface (JNI) that allows interaction with libraries written in languages like C and C++. JNI has always been fiddly to use, and this task is simplified substantially with these APIs. The introduction of the Java Platform Module System in JDK 9 also led to the encapsulation of internal APIs. This JEP also provides public APIs for some of the internal ones like the infamous sun.misc.Unsafe class. This internal API was never intended for application development, but that didn’t stop people from using it, so now there are publicly accessible alternatives.
The Vector API (not to be confused with the Vector collections class) has been moved to a fourth incubator iteration. Most of the changes since the previous release relate to its integration with the Foreign Function and Memory API described above.
JEP 422: Linux/RISC-V Port (incubator)
Outside of programmatic features, there is JEP 422, a port of OpenJDK to Linux on the RISC-V chip architecture. There are not many actual RISC-V devices you can buy right now, but this is a promising-looking platform, so Java support will be beneficial.
As you can see, JDK 19 continues the controlled pace of development for the Java platform, maintaining a steady flow of enhancements. After 27 years, it’s great to see Java continue to evolve and address developers’ changing needs. It’s no wonder Java is consistently in the top three most popular languages!
What’s in the Azul Platform Prime JDK 19 preview
We’re happy to announce that the Azul Platform Prime Preview build of JDK 19 is now available. You can download and freely use this JDK 19 preview for development and testing to explore the newest JDK features together with the world’s fastest JVM.
Our JDK 19 preview builds contains the following JEPs from JDK 19:
These JEPs are not included in the preview build – but will be included in future releases:
- JEP 422: Linux/RISC-V Port
- JEP 424: Foreign Function & Memory API (Preview)
- JEP 425: Virtual Threads (Preview)
- JEP 426: Vector API (Fourth Incubator)
- JEP 428: Structured Concurrency (Incubator)
We’ve delivered notable improvements to our high-performance JVM:
- Compile time / warmup improvements – significantly reducing the time needed for the JVM to optimize the code to maximum performance
- Reduced thread allocation delays
- Further performance improvements
Stay tuned for our General Availability (GA) release is planned for the end of October.
Download the Azul Platform Prime JDK 19 Preview and give it a try. Make sure to read our new What to Expect guide and then get started!
Senior Product Manager for Platform Prime Jiří Holuša contributed to his blog post.