Understanding the Java 20 Release

By Mateusz Skawiński

Introducing Java 20 

Java 20 was released on Tuesday, March 21st. Six months after the previous release, we have another short-term version (non-LTS). As expected, there are no huge updates in Java 20 since the LTS (long-term support) version of Java 21 is planned for September this year, but we still have a bunch of interesting new features.  

Let’s jump in and have a look at them. 

JDK Enhancement Proposals 

The new release has 7 JEPs (JDK Enhancement Proposals). We’ve already seen most of these features in earlier versions, but Java 20 provides further updates for these enhancements. One of the new – and most interesting – features for this release is Scoped Values.  

The new JDK version introduces the first iteration of the incubator for this feature, and even though the final version will likely look different, it’s definitely worth taking a closer look as it shows that Java is taking another step towards modern languages after the programming and data processing trends.   

Scoped Values 

Scoped Values is an incubating API intended to allow values to be shared within the thread. With it, static references can be made to values that differ for each thread without the need to pass the reference through several methods of invocation chains.  

This could be especially important if you are combining a method invocation with an un-owned implementation. It may sound similar to the ThreadLocalAPI (introduced in the 1.2 Java version), but it has several differences that make it a better, more efficient tool for modern programming. 

Here are the benefits of Scoped Values vs ThreadLocal: 

  • Scoped Values are immutable. Unlike ThreadLocal, they cannot be modified, allowing a Scoped Values implementation to be more efficient. Mutability brings additional complexity, and since the need for modification is rare, Scoped Values is a more effective choice.  
  • Scoped Values scope is limited to a running method, helping to prevent unnecessary memory usage. While using Scoped Values, we have a method that should be run as a Lambda, Runnable, or Callable interface. Defined values for the thread will be available in the scope of this method execution, while the ThreadLocal API would make its variable available until either the end of the thread or explicit remove () call. The latter is more likely to keep the variable reference longer than it is actually needed, making it ineligible for a garbage collector and leading to memory leaks.  
  • Better memory utilization on new thread creation. While creating a new thread, ThreadLocal values will be copied from parent to child. This is needed, as changes made in one should not be reflected in the other. But since Scoped Values are immutable, there is no need to copy this data – it can be shared directly, saving some of the memory needed for the allocation of these objects for the new thread. 
  • Scoped Values is a better fit for modern approaches, like virtual threads. Virtual threads were introduced in Java 19 (JDK 20 also provides the next version of the feature). With that functionality, an application might not use dozens of OS-based threads in favor of using thousands of virtual ones. This could be useful for building web server implementations which would process each request in separately created threads. In this scenario, the more efficient memory usage of Scoped Values (as described above), is crucial.  

Using Scoped Values 

Using this new feature is pretty simple. The first thing we need to do is to declare a scoped value, which we will usually specify as a static final class field: 

static final ScopedValue<String> USERNAME = ScopedValue.newInstance(); 

Once the value is declared, we can assign its value and execute a method within which scope the defined value will be available. We have a few options here – run(), call(), or overloaded where() methods. In our example, we use an approach with run() and Lambda implementing a Runnable interface. 

ScopedValue.where(USERNAME, someName).run(() -> doSomething()); 

Then, within the doSomething method scope and down its invocations’ stack, each thread can reference its copy of USERNAME by: 

var name = ClassName.USERNAME.get(); 

Other New Features 

Java 20 has six more JEPs. But since these represent new previews or incubator versions of features already included in past versions of Java, you may already be familiar with these topics. Updated versions of features include further changes based on experience and feedback from previously proposed versions along with improvements that result from the co-evolution of other new JEPs. New versions of JEPs targeting the new Java release come from three projects: Amber, Loom, and Panama.  

Project Amber  

Project Amber explores and incubates smaller, productivity-oriented Java language features. This release includes two items from Project Amber: Record Patterns and Pattern Matching for switch. These are tools you would use in everyday programming work, regardless of the type of software you develop. They simplify common work with data objects and control flow instructions by following programming approaches that can be found in other modern languages, like Kotlin. 

Project Loom 

If you’re interested in easy-to-use, high-throughput, lightweight concurrency programming, look deeper into Project Loom. The latest Java includes three JEPs related to this project: Virtual Threads, Structured Concurrency, and already discussed Scoped Values. 

Project Panama 

Lastly, Project Panama aims to interconnect Java code (JVM applications) with external code that runs on non-Java runtime. It comes with two APIs: Foreign Function & Memory API and Vector API 

The Complete List 

A full list of new enhancements and a brief summary of their features is presented below. Detailed information about each feature can be found here and on related links. 

  • Scoped Values (JEP 429) – Enables the sharing of immutable data within and across threads. This is preferable to thread-local variables. 
  • Record Patterns (JEP 432) – Allows the deconstruction of record values. Record patterns and type patterns can be nested to enable a powerful, declarative, and composable form of data navigation and processing.  
  • Pattern Matching for Switch (JEP 433) – This extension allows an expression to be tested against a number of patterns, each with a specific action. 
  • Foreign Function & Memory API (JEP 434) – An API by which Java programs can interact with code and data outside of Java runtime. It enables Java programs to call native libraries and process native data without the brittleness and danger of JNI. 
  • Virtual Threads (JEP 436) – Lightweight threads that dramatically reduce the effort of writing, maintaining, and observing high-throughput concurrent applications. 
  • Structured Concurrency (JEP 437) – Treats multiple tasks running in different threads as a single unit of work, thereby streamlining error handling and cancellation, improving reliability, and enhancing observability. 
  • Vector API (JEP 438) – An API to express vector computations that reliably compile at runtime to optimize vector instructions on supported CPU architectures. 

Why These Changes Matter 

The changes in the new Java release may not seem like major breakthroughs, but we can certainly see some meaningful improvements to the platform. With these changes, we can also see the direction that Java is evolving, and we can set some expectations for Java 21.  

The following version (JDK 21) will surely become more popular, as it will be an LTS version with five years of support provided by Oracle. Many companies will prefer to adopt the LTS version, but if you’re currently working on a new solution and/or can flexibly switch the version of JDK in your solution, the newly released Java 20 is a good option.

Mateusz Skawiński

Mateusz Skawiński is a Java Development Lead at Customertimes Corp with more than 13 years of commercial experience in software development. He specializes in the design and development of large enterprise applications based on the Java technology stack, as well as the creation of system integrations on IPaaS platforms.

figure

Product Development at Customertimes

Our expert Java developers can help with every step of your product development journey. Find out more about our unique labs-based approach, and then let's get to work.

Learn More