Java 21, released in September 2023, is widely considered the most impactful Long-Term Support (LTS) release since Java 8. It finalized several massive projects—most notably Project Loom—that fundamentally changed how Java handles concurrency and data modeling.
This is the "crown jewel" of Java 21. For decades, one Java thread equaled one Operating System (OS) thread. OS threads are expensive and limited (usually to a few thousand).
- The Enhancement: Virtual threads are lightweight threads managed by the JVM, not the OS. They are "mounted" onto platform threads only when executing code.
- The "Why": You can now start millions of threads on a single machine. This makes the "thread-per-request" model highly scalable without needing complex reactive programming (like WebFlux).
- Performance Impact: Dramatic reduction in RAM usage for high-concurrency applications (e.g., web servers handling 100k+ simultaneous connections).
// Creating a task
Runnable task = () -> {
System.out.println("Processing on: " + Thread.currentThread());
};
// Method 1: Start a single virtual thread
Thread.startVirtualThread(task);
// Method 2: Use an Executor (Best for Web Servers)
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(task);
});
} // Executor auto-closes, waiting for all 10,000 threads to finishThis feature turns the humble switch statement into a powerful tool for data analysis and logic branching.
- The Enhancement:
switchcan now test types, check fornull, and include conditional "guards" (usingwhen). - The "Why": It removes the "if-else-if" chains and repetitive
instanceofchecks with manual casting.
static String formatter(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);
case null -> "It's a null value";
default -> obj.toString();
};
}
// Using "when" clauses (Guards)
static String response(Object obj) {
return switch (obj) {
case String s when s.equalsIgnoreCase("YES") -> "User agreed";
case String s when s.equalsIgnoreCase("NO") -> "User declined";
case String s -> "Invalid input: " + s;
default -> "Not a string";
};
}Working in tandem with Pattern Matching, Record Patterns allow you to "deconstruct" a record into its variables in one step.
- The Enhancement: You can "pull apart" a Record directly within an
instanceofcheck orswitchcase. - The "Why": It eliminates boilerplate code like
Point p = (Point) obj; int x = p.x();.
record Point(int x, int y) {}
public void printPoint(Object obj) {
// Deconstruction happens right in the check
if (obj instanceof Point(int x, int y)) {
System.out.println("Coordinates: " + x + ", " + y);
}
}Surprisingly, until Java 21, there was no uniform way to get the "first" or "last" element of a collection in a consistent manner (e.g., List vs. LinkedHashSet).
- The Enhancement: New interfaces (
SequencedCollection,SequencedSet,SequencedMap) provide a uniform API. - The Impact: Cleaner code when working with any collection that has a defined order.
var list = new ArrayList<>(List.of("One", "Two", "Three"));
list.addFirst("Zero"); // New method
list.addLast("Four"); // New method
String first = list.getFirst(); // "Zero"
String last = list.getLast(); // "Four"
// Reverse the view without copying the data
SequencedCollection<String> reversed = list.reversed();A critical update for modern security, especially in high-compliance environments.
- The Enhancement: A new API for Key Encapsulation Mechanisms (KEMs), a modern cryptographic technique that secures symmetric keys using public-key cryptography.
- The "Why": Necessary for integrating Post-Quantum Cryptography (PQC) and modern protocols like TLS 1.3 more robustly.
While ZGC (Z Garbage Collector) existed before, Java 21 made it "Generational."
- The Enhancement: ZGC now separates objects into "young" and "old" generations.
- The Impact: It can reclaim memory from short-lived objects (like those created in web requests) much more efficiently, maintaining sub-millisecond pause times while using significantly less CPU and RAM.
| Feature | Category | Primary Benefit |
|---|---|---|
| Virtual Threads | Concurrency | Scale to millions of tasks with simple code. |
| Pattern Matching | Language | Clean, expressive logic without casting. |
| Sequenced Collections | API | Consistent way to handle ordered data. |
| Record Patterns | Language | Easy deconstruction of data objects. |
| Generational ZGC | Performance | Ultra-low latency GC for heavy workloads. |