← 開発ノート

Java 21 の機能:仮想スレッド・順序付きコレクション・プレビューの境界

仮想スレッド、順序付きコレクション、レコードパターン、switch のパターンマッチングは JDK 21 の正式機能であり、プレビューオプションなしで使えます。文字列テンプレートはこのリリースではまだプレビュー機能でした。JDK の更新ですべての新機能が同じ安定性の状態になるわけではありません。JDK 21 リリースノートでも正式・プレビュー・インキュベーター機能を区別しています。

Java 21 は 2023年9月19日に一般提供されました。この記事は再現可能な例でそのリリースを振り返ります。最新 JDK や本番用のパッチバージョンを推奨するものではありません。

処理の流れ

プレビューオプションを使わない Jdk21Example の流れです。逆順リストはビューであり、join は仮想スレッドの出力を待ちます。

プレビューオプションを使わない Jdk21Example の流れです。逆順リストはビューであり、join は仮想スレッドの出力を待ちます。

JDK 21 での機能の状態

機能 JDK 21 での状態 確認すること
仮想スレッド 正式 多数の I/O 中心のタスクで検討する。CPU 計算の高速化は保証しない
順序付きコレクション 正式 先頭・末尾要素と逆順ビューの一貫した API
レコードパターンと switch のパターンマッチング 正式 値を分解してパターンで分岐する
文字列テンプレート プレビュー 後の JDK にも残ると仮定しない
構造化並行処理 プレビュー 仮想スレッドの正式化とは別に評価する
Vector API 第六次インキュベーター 正式機能・プレビュー機能と区別する

これは一部の機能です。JDK 21 リリースノートにもプレビューとインキュベーターの状態が記載されています。言語機能は Java 21 の言語変更で確認してください。文字列テンプレートは JDK 23 に含まれませんでした。経緯と標準の代替手段を参照してください。

プレビューオプションなしでコンパイル

以下のコードはローカルの Zulu JDK 21.0.1 で実行しました。この古いパッチバージョンは再現環境の記録であり、本番向けの推奨ではありません。まず javac と java が同じ JDK 21 を参照することを確認してください。

Jdk21Example.java

import java.util.ArrayList;
import java.util.List;

public class Jdk21Example {
    record Point(int x, int y) {}

    static String describe(Object value) {
        return switch (value) {
            case null -> "missing";
            case Point(int x, int y) -> "point=" + x + "," + y;
            default -> "other";
        };
    }

    public static void main(String[] args) throws InterruptedException {
        var names = new ArrayList<>(List.of("alpha", "beta", "gamma"));
        var reverse = names.reversed();
        names.set(0, "ALPHA");
        System.out.println(names.getFirst() + "/" + names.getLast());
        System.out.println(reverse);
        System.out.println(describe(new Point(2, 3)));
        System.out.println(describe(null));
        Thread worker = Thread.ofVirtual().start(() ->
                System.out.println("virtual=" + Thread.currentThread().isVirtual()));
        worker.join();
    }
}
javac --release 21 Jdk21Example.java
java Jdk21Example
ALPHA/gamma
[gamma, beta, ALPHA]
point=2,3
missing
virtual=true

reversed() は独立したコピーではなく逆順ビューを返します。元のリストの先頭要素を変更すると、逆順出力の末尾も ALPHA になります。空のコレクションで getFirst() を呼ぶと例外になりますが、この例では空でないリストを使います。ビューの契約は SequencedCollection APIに定義されています。

Point(int x, int y) はレコードパターンで、case null は null 入力を個別に処理します。最後の行は仮想スレッドが出力し、join() が完了を待ちます。API の動作確認であり、スループットや遅延は測りません。仮想スレッドガイドは I/O 待ちが中心の並行処理への適性を説明しています。

アプリのランタイムを変更する前に、フレームワーク・ビルドツール・計測エージェントの JDK 21 互換性を確認してください。JDK の機能状態と配布元のサポート期間は別の問題です。Temurin 21 のリリース履歴とバイナリー選択では、配布元が実際に公開したものの確認方法を扱います。

コメント

GitHubで見る ↗