Java 20 extends concurrency with scoped values

Oracle released Java 20 every six months as planned. The release brings a total of seven innovations in Java Enhancement Proposals (JEPs), three of which come from Project Loom and two each from the Amber and Panama projects. Six of the JEPs are evolutions from previous JDKs. Only the scoped values ​​are completely new.



In the overview, Oracle is exceptionally deep: JDK 20 does not bring six, but seven JEPs.

(Image: Oracle)

Project Loom aims to improve and streamline concurrency for Java programs. Loom means loom, i.e. the tool to join the threads into a large whole. Java 20 weaves a new thread into the incubator and extends two JEPs from Java 19.

JEP 436 Virtual Threads started as JEP 425 in Java 19. It denotes a new concept for concurrent applications. Traditionally, in multi-threaded applications, Java used a thread in the operating system for every thread in the code. The virtual threads conserve resources by introducing an intermediate level in the JDK that takes care of distributing the threads in the code to those in the operating system.

In Java, version 1.1 already had the concept of green threads, in which the JDK took over the distribution. However, it put all the code threads on just one in the operating system. The new concept, on the other hand, is designed to use a limited number of operating system threads for a large number of virtual threads. The runtime also takes care of pausing virtual threads that call a blocking operation. The proposal is in the second preview phase.

The JEP 429 Scoped Values ​​introduces a new concept for exchanging immutable values ​​within and between threads. It is more efficient than using ThreadLocal-Variables. Like these, the values ​​apply in principle only to the respective thread. The same ScopedValue can have different values ​​in different threads. Typically, one should use Scoped Values ​​as public static implement. Scope is to be understood differently than usual in Java: It is not the lexical area of ​​a class or function, but a dynamic area that the runtime specifies by binding the value.

Compared to the ThreadLocalvariables, the Scoped Values ​​have some advantages. On the one hand, they are fundamentally immutable and new content can only be assigned via rebinding, while ThreadLocal-Variables about set can change the value. This makes it difficult to understand which codes can change the values ​​at what time.

In addition, the scoped values ​​have a fixed lifetime: For the call

ScopedValue.where(V, <value>)
           .run(() -> { ... V.get() ...  });

the runtime creates a specific value and binds it to the context in run. The code called within it has access to the value, and once the method run is finished, the runtime releases the binding, which allows the garbage collector to clean up the value. A manual ThradLocal.remove() is therefore superfluous – and does not lead to unnecessary memory being used if someone forgets to remove it manually. In addition, child threads can automatically access the parent’s scoped values ​​and thus do not occupy any additional memory.

The JEP 437 Structured Concurrency continues the proposal introduced in Java 19 with the same description as JEP 428. Like the new Scoped Values, it is in the incubator. This means that, in contrast to the preview features, the API has not yet been fully specified. With the concept of structured concurrency, also offered by other languages ​​and frameworks, tasks from different threads can be managed in one unit to improve the maintainability and reliability of concurrent code.

With the class StructuredTaskScope you can create a task as a group of concurrent subtasks and manage it as a closed unit. The API knows, among other things, the default ShutdownOnFailure, which ensures that if an error occurs in one subtask, the other tasks are stopped accordingly. Analogously there ShutdownOnSuccess stipulates that all subtasks finish their work when one has run successfully.

The two proposals for Project Amber tie in seamlessly with the previous Java version. The “Bernstein” project contains smaller language features that are primarily intended to increase productivity. JEP 432 Record Patterns is the second preview after JEP 405 in JDK 19. It is used to deconstruct values ​​in records, whereby the patterns may be nested.

JEP 433 Pattern Matching for switch is already the fourth preview and thus the third successor to the proposal introduced in Java 17 under 406. For Java 21, the final integration with JEP 441 is pending. The name is more or less self-explanatory: The construct uses a switch block to compare an expression with patterns, for example the following code from the JEP

static String formatter(Object obj) {
    String formatted = "unknown";
    if (obj instanceof Integer i) {
        formatted = String.format("int %d", i);
    } else if (obj instanceof Long l) {
        formatted = String.format("long %d", l);
    } else if (obj instanceof Double d) {
        formatted = String.format("double %f", d);
    } else if (obj instanceof String s) {
        formatted = String.format("String %s", s);
    }
    return formatted;
}

through the clearly more readable

static String formatterPatternSwitch(Object obj) {
    return switch (obj) {
        case Integer i -> String.format("int %d", i);
        case Long l    -> String.format("long %d", l);
        case Double d  -> String.format("double %f", d);
        case String s  -> String.format("String %s", s);
        default        -> o.toString();
    };
}
}

to replace.

The two proposals for Project Panama also only go one step forward compared to Java 19. The project aims to connect Java programs to non-Java or JVM components such as C-based libraries and interfaces.

JEP 434 Foreign Function & Memory API is the second preview after JEP 424 in JDK 19. The proposal is intended to provide a uniform interface to code and data beyond the Java runtime and to replace the Java Native Interface (JNI). The API, which goes by the acronym FFM, combines the JEP 389 Foreign Linker API from Java 16 and the Foreign-Memory Access API launched in Java 14 as JEP 370.

The last major innovation in Java 20 JEP 438 Vector API is already in the fifth incubator round, so it has been on board since Java 16. The API is intended to provide an interface for vector calculations at the CPU level.

As usual, Java 20 also brings some bug fixes. More about the innovations can be found in the Java blog at Oracle. In autumn, JDK 21 is a major step ahead for Java: the next release with long-term support.

The OpenJDK variant can be downloaded from the JDK site. For the commercial variant, Oracle adjusted the license model at the end of January: The price for the new Oracle Java SE Universal Subscription is no longer based on the actual Java user (“Named User Plus” license) or the number of processors (“Processor” license) , but according to the number of employees in the company, which potentially has to include partners such as agents, consultants and outsourcers. Oracle praises the model as simpler, but for most companies it is likely to be more expensive.


(rm)

To home page

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *