What’s New in Java 21? Exploring LTS Features, ZGC, and Virtual Threads
This article reviews the Java 21 LTS release, lists its new JEPs, shares an upgrade experience from Java 17, evaluates the generational ZGC and virtual‑thread improvements, demonstrates record‑pattern syntax, and provides code samples and performance observations.
Introduction
Oracle recently released Java 21 as the latest LTS version, attracting wide attention. The author upgraded a personal project to Java 21 and shares the experience.
Java 21 Update Overview
Official release notes: https://jdk.java.net/21/release-notes . Open‑source community introduction: https://my.oschina.net/waylau/blog/10112170 .
New Features (JEPs)
JEP 431: Sequenced Collections
JEP 439: Generational ZGC
JEP 440: Record Patterns
JEP 441: Switch Pattern Matching
JEP 444: Virtual Threads
JEP 449: Deprecate Windows x86 32‑bit Port
JEP 451: Prepare to Disallow Dynamic Loading of Agents
JEP 452: Key Encapsulation Mechanism API
JEP 430: String Templates (Preview)
JEP 442: Foreign Function & Memory API (Third Preview)
JEP 443: Unnamed Patterns and Variables (Preview)
JEP 445: Unnamed Classes and Instance Main Methods (Preview)
JEP 446: Scoped Values (Preview)
JEP 453: Structured Concurrency (Preview)
JEP 448: Vector API (Sixth Incubator Phase)
Among these, developers are most interested in Generational ZGC and Virtual Threads.
Upgrade Experience
Download links:
OpenJDK: https://jdk.java.net/21/
Oracle: https://www.oracle.com/java/technologies/downloads/
Compared with Java 17, the JDK’s “frame” changed from stainless steel to titanium, the directory structure remains the same, but the module count is reduced by one and the overall size grew from 289 MB to 320 MB.
Compatibility check showed good results with only one issue: a character‑set problem in a system‑tray PopupMenu.
Generational ZGC Experience
Generational ZGC, introduced in earlier JDK versions, offers lower allocation‑stall risk, reduced heap overhead, and lower GC CPU usage. Enable it with -XX:+UseZGC -XX:+ZGenerational.
Performance test reference: https://inside.java/2023/09/03/roadto21-performance/ .
Virtual Threads Exploration
Virtual threads are lightweight threads that simplify writing, maintaining, and debugging high‑throughput concurrent applications. Unlike platform (OS) threads, they do not have a one‑to‑one mapping to OS threads and can be parked while blocked I/O operations are pending.
Key characteristics (from Oracle documentation):
Implemented as a thin wrapper over OS threads.
Run Java code on underlying OS threads for the whole lifecycle.
Number limited by OS thread count.
Typically have large stack and OS‑managed resources.
Support thread‑local variables.
Suitable for tasks that spend most time blocked on I/O.
Example usage:
Thread thread = Thread.ofVirtual().start(() -> System.out.println("Hello"));
thread.join(); try {
Thread.Builder builder = Thread.ofVirtual().name("MyThread");
Runnable task = () -> System.out.println("Running thread");
Thread t = builder.start(task);
System.out.println("Thread t name: " + t.getName());
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
} Thread.startVirtualThread(() -> {
// do something
});Record Patterns (Syntax Sugar)
Before (using instanceof):
static void printSum(Object obj) {
if (obj instanceof Point p) {
int x = p.x();
int y = p.y();
System.out.println(x + y);
}
}After (using record pattern):
static void printSum(Object obj) {
if (obj instanceof Point(int x, int y)) {
System.out.println(x + y);
}
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
