Choosing a JDK Distribution Java 21 is open source (OpenJDK). Multiple vendors distribute binaries, all built from the same source with identical features. Choose based on your support requirements: Distribution Vendor Free LTS Support Notes Eclipse Temurin Adoptium Yes 2028+ Recommended for most developers OpenJDK Oracle/Community Yes 6 months only Reference implementation, no LTS Oracle JDK Oracle Yes (NFTC) 2031 Identical to OpenJDK since Java 17 Amazon Corretto AWS Yes 2030+ Good for AWS deployments Microsoft Build of OpenJDK Microsoft Yes Long-term Good for Azure deployments Azul Zulu Azul Yes/Paid Long-term Includes Zing JVM variant GraalVM Oracle Yes Long-term Adds native-image, polyglot Recommendation: Eclipse Temurin for local development; match your cloud provider’s JDK for production (Corretto on AWS, Microsoft OpenJDK on Azure).
Continue reading »Java 21 Tutorial
16 posts in this section
Structured Concurrency (JEP 453): Safe, Readable Concurrent Code
Preview Feature — Requires --enable-preview at compile and runtime. The API stabilized significantly from Java 21 through 24 and will be finalized in a future release. The Unstructured Concurrency Problem When you submit tasks to an ExecutorService, the tasks are logically related but structurally unconnected — the executor doesn’t know they belong together: // Unstructured concurrency — looks simple, hides serious problems ExecutorService executor = Executors.newCachedThreadPool(); Future<Order> orderFuture = executor.
Continue reading »Unnamed Classes and Instance Main Methods (JEP 445): Java for Scripts and Beginners
Preview Feature — Requires --enable-preview at compile and runtime. The Boilerplate Problem Teaching Java to a beginner means explaining class declarations, access modifiers, static, and String[] before they can print “Hello, World!”: // Traditional Java — 4 concepts before printing one line public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } Every word carries meaning, but that meaning is irrelevant until the student understands OOP, the JVM class model, and program entry points.
Continue reading »Unnamed Patterns and Variables (JEP 443): Writing Intent-Clear Code
Preview Feature — Requires --enable-preview at compile and runtime. The _ identifier was reserved in Java 9; this JEP gives it formal semantics. The Problem: Forced Naming of Unused Things When pattern matching, you often care about only some components of a matched structure. But the syntax forces you to name everything: record Point(int x, int y) {} record ColoredPoint(Point point, String color) {} record Box(ColoredPoint cp, int weight) {} // You only care about the color — but must name everything else if (obj instanceof Box(ColoredPoint(Point(int x, int y), String color), int weight)) { System.
Continue reading »Vector API (JEP 448): SIMD Computation in Java
Preview Feature in Java 21 — The Vector API has been in preview since Java 16 (JEP 338). JEP 448 is the sixth preview iteration in Java 21. The API is stable and production-usable with --enable-preview; finalization is pending Project Valhalla value types. What Is SIMD and Why Does It Matter? Modern CPUs can perform the same arithmetic operation on multiple data values in a single instruction. This is called SIMD — Single Instruction, Multiple Data.
Continue reading »Virtual Threads (JEP 444): A Million Threads Without the Pain
The Platform Thread Problem Every Java thread since Java 1.0 maps 1:1 to an OS thread. OS threads are heavy: Stack memory: 512 KB – 2 MB per thread (configurable with -Xss, default 512 KB on Linux) Context switch cost: ~1–10 μs per switch (kernel mode transition + cache invalidation) Hard limit: A 64-bit machine with 8 GB RAM can support roughly 8,000–16,000 OS threads before running out of stack memory This limit shapes how Java servers are built.
Continue reading »