Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

What's new for developers in JDK 21

New features in Java 21

September 21, 2023
Syed M Shaaf
Related topics:
Java
Related products:
Red Hat build of OpenJDK

Share:

    In an exciting development for Java developers, this September 19th marked the release of JDK 21. This release contains many new capabilities that benefit the Java ecosystem, including virtual threads, record patterns, and sequenced collections. There are also some interesting features in the preview for JDK 21, such as string templates, scoped values, and structured concurrency. This article highlights six new features in this release.

    Virtual threads

    Java's traditional threading model can quickly become an expensive operation if the application creates more threads than the operating system (OS) can handle. Also, in cases where the thread lifecycle is not long, the cost of creating a thread is high.

    Enter virtual threads, which solve this problem by mapping Java threads to carrier threads that manage (i.e., mount/unmount) thread operations to a carrier thread. In contrast, the carrier thread works with the OS thread. It is an abstraction that gives more flexibility and control for developers. See Figure 1.

    JDK 21's new virtual threading model, in which Java threads are mapped to carrier threads.
    Figure 1: The virtual threading model in JDK 21.

    The following is an example of virtual threads and a good contrast to OS/platform threads. The program uses the ExecutorService to create 10,000 tasks and waits for all of them to be completed. Behind the scenes, the JDK will run this on a limited number of carrier and OS threads, providing you with the durability to write concurrent code with ease.

    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

    Structured concurrency (Preview)

    Structured concurrency is closely tied to virtual threads, and it aims to eliminate common risks such as cancellation, shutdown, thread leaks, etc., by providing an API that enhances the developer experience. If a task splits into concurrent subtasks, then they should all return to the same place, i.e., the task's code block.

    In Figure 2, findUser and fetchOrder both need to execute to get the data from different services and then use that data to compose results and send it back in a response to the consumer. Normally, these tasks could be done concurrently and could be error prone if findUser didn't return; fetchOrder would need to wait for it to complete, and then finally execute the Join operations.

    Structured concurrency example.
    Figure 2: Structured concurrency example.

    Furthermore, the lifetime of the subtasks should not be more than the parent itself. Imagine a task operation that would compose results of multiple fast-running I/O operations concurrently if each operation is executed in a thread. The structured concurrency model brings thread programming closer to the ease of single-threaded code style by leveraging the virtual threads API and the StructuredTaskScope.

    Response handle() throws ExecutionException, InterruptedException {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            Supplier<String>  user  = scope.fork(() -> findUser());
            Supplier<Integer> order = scope.fork(() -> fetchOrder());
    
            scope.join()            // Join both subtasks
                 .throwIfFailed();  // ... and propagate errors
    
            // Here, both subtasks have succeeded, so compose their results
            return new Response(user.get(), order.get());
        }
    }

    Scoped values (Preview)

    ScopeValue also brings in interesting changes for developer productivity when programming with Threads. Historically, Java developers have used ThreadLocals to pass along data through the call chain in order for a thread to access data. However, changing that data through the call chain is also easier as the ThreadLocal variable passes through. This makes it harder to program and sometimes more error prone, with risks to insecure code.

    ScopeValue aims to fix this by providing a model where threads can share data without the possibility of changing it during its scope. The data is immutable with the ScopeValue and enables runtime optimization. 

    Multi-threaded applications that use security principals, transactions, and shared context will benefit from the scoped values. The example below shows the ScopeValue<String>, which is created and used with the scope of runWhere, a runnable method.

    public class WithUserSession {
    	// Creates a new ScopedValue
    	private final static ScopedValue<String> USER_ID = new ScopedValue.newInstance();
    
    	public void processWithUser(String sessionUserId) {
    		// sessionUserId is bound to the ScopedValue USER_ID for the execution of the 
    		// runWhere method, the runWhere method invokes the processRequest method.
    		ScopedValue.runWhere(USER_ID, sessionUserId, () -> processRequest());
    	 }
    	 // ...
    }

    Sequenced collections

    In JDK 21, a new set of collection interfaces are introduced to enhance the experience of using collections (Figure 3). For example, if one needs to get a reverse order of elements from a collection, depending on which collection is in use, it can be tedious. There can be inconsistencies retrieving the encounter order depending on which collection is being used; for example, SortedSet implements one, but HashSet doesn't, making it cumbersome to achieve this on different data sets.

    Sequenced collections diagram.
    Figure 3: Sequenced Collections.

    To fix this, the SequencedCollection interface aids the encounter order by adding a reverse method as well as the ability to get the first and the last elements. Furthermore, there are also SequencedMap and SequencedSet interfaces. 

    interface SequencedCollection<E> extends Collection<E> {
        // new method
        SequencedCollection<E> reversed();
        // methods promoted from Deque
        void addFirst(E);
        void addLast(E);
        E getFirst();
        E getLast();
        E removeFirst();
        E removeLast();
    }
    

    So now, not only is it possible to get the encounter order, but you can also remove and add the first and last elements.

    Record patterns

    Records were introduced as a preview in Java 14, which also gave us Java enums. record is another special type in Java, and its purpose is to ease the process of developing classes that act as data carriers only.

    In JDK 21, record patterns and type patterns can be nested to enable a declarative and composable form of data navigation and processing.

    // To create a record:
    
    Public record Todo(String title, boolean completed){}
    
    // To create an Object:
    
    Todo t = new Todo(“Learn Java 21”, false);
    
    

    Before JDK 21, the entire record would need to be deconstructed to retrieve accessors.. However, now it is much more simplified to get the values. For example:

    static void printTodo(Object obj) {
        if (obj instanceof Todo(String title, boolean completed)) {
            	System.out.print(title);
    System.out.print(completed);
        }
    }
    

    The other advantage of record patterns is also nested records and accessing them. An example from the JEP definition itself shows the ability to get to the Point values, which are part of ColoredPoint, which is nested in a Rectangle. This makes it way more useful than before, when all the records needed to be deconstructed every time. 

    // As of Java 21
    static void printColorOfUpperLeftPoint(Rectangle r) {
        if (r instanceof Rectangle(ColoredPoint(Point p, Color c),
                                   ColoredPoint lr)) {
            System.out.println(c);
        }
    }
    

    String templates

    String templates are a preview feature in JDK 21. However, it attempts to bring more reliability and better experience to String manipulation to avoid common pitfalls that can sometimes lead to undesirable results, such as injections. Now you can write template expressions and render them out in a String. 

    // As of Java 21
    String name = "Shaaf"
    String greeting = "Hello \{name}";
    System.out.println(greeting);
    

    In this case, the second line is the expression, and upon invoking, it should render Hello Shaaf. Furthermore, in cases where there is a chance of illegal Strings—for example, SQL statements or HTML that can cause security issues—the template rules only allow escaped quotes and no illegal entities in HTML documents.

    Get support for Java

    Support for OpenJDK and Eclipse Temurin is available to Red Hat customers through a subscription to Red Hat Runtimes, Red Hat Enterprise Linux, and Red Hat OpenShift. Contact your local Red Hat representative or Red Hat sales for more details. You can expect support for Java and other runtimes as described under the Red Hat Product Update and Support Lifecycle.

    Resources

    • Catch up with the latest on Java

    • Video: What is Eclipse Temurin?

    • Getting started with Eclipse Temurin

    • Red Hat joins the Eclipse Adoptium Working Group

    • Eclipse Adoptium achieves its first Java SE release

    • Red Hat Introduces Commercial Support for OpenJDK on Microsoft Windows

    • The history and future of OpenJDK

    Last updated: October 5, 2023

    Related Posts

    • Beyond Loom: Weaving new concurrency patterns

    • Best practices for Java in single-core containers

    • How to migrate your Java applications to Red Hat OpenShift

    • Use design by contract to build Kubernetes Operators in Java

    • Quick Java application setup using Kafka messaging

    • Red Hat expands support for Java with Eclipse Temurin

    Recent Posts

    • Alternatives to creating bootc images from scratch

    • How to update OpenStack Services on OpenShift

    • How to integrate vLLM inference into your macOS and iOS apps

    • How Insights events enhance system life cycle management

    • Meet the Red Hat Node.js team at PowerUP 2025

    What’s up next?

    java-nutshell-cover_Share

    Download Java in a Nutshell, the reference guide every Java developer needs at their fingertips. This book helps you get the most out of versions through Java 17, with examples that show how to take advantage of modern Java APIs and development best practices.

    Get the e-book
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue