$30 off During Our Annual Pro Sale. View Details »

Java 21 Overview

Java 21 Overview

Yoshida Shinya (@shinyafox, @bitter_fox)
LINE Corporation
2023/09/28

LINE Developers
PRO

September 28, 2023
Tweet

More Decks by LINE Developers

Other Decks in Technology

Transcript

  1. Java 21 Overview
    Yoshida Shinya (@shinyafox, @bitter_fox)
    LINE Corporation
    2023/09/28

    View Slide

  2. Who am I
    • Senior Serverside Engineer at LINE Corporation
    • Leader of HBase team for LINE Messenger Backend
    • Contributed to Java 8, 9
    • Project Lambda Contributor
    • Project Kulla (jshell) Committer
    • JJUG Board member
    • Recent work
    • Modernize Java version for HBase/Hadoop
    • From Java 8 to Java 17 with new HBase/Hadoop version
    • Evaluate ZGC for HBase

    View Slide

  3. Agenda
    • Javaの開発とリリース
    • 最近のJavaリリースの振り返り
    • Java 21 JEPs
    • Language
    • API
    • JVM&Runtime
    • Project Loom
    • Project Panama

    View Slide

  4. Javaの開発とリリース
    • 開発:OpenJDK(OSS Community) hosted on GitHub
    • https://openjdk.org
    • https://github.com/openjdk/jdk
    • 開発課題: Jira, JEP (JDK Enhancement Proposal)
    • https://bugs.openjdk.org
    • https://openjdk.org/jeps
    • 仕様: JSR (Java Specification Request)
    • Java 21 https://www.jcp.org/en/jsr/detail?id=396
    • リリース: 6ヶ月ごと
    • LTS (Long Term Support)
    • OpenJDK: LTSバージョンは指定していない
    • 各ベンダー: どのバージョンを長期的にサポートするか
    • Oracle: Java 11 (3年) Java 17 (2年) Java 21 (2年) Java 25 ...をLTSに

    View Slide

  5. JEP – JDK Enhancement Proposal
    • PEP: Python Enhancement Proposalを参考にして導入された
    • Java Platformの大きな新機能、開発、変更の提案
    • メタ的な提案
    • JEP 1: JDK Enhancement-Proposal & Roadmap Process
    • JEP 328: Flight Recorder
    • JEP 110: HTTP/2 Client (Incubator)
    • JEP 321: HTTP Client
    • JEP 325: Switch Expressions (Preview)
    • JEP 354: Switch Expressions (Second Preview)
    • JEP 361: Switch Expressions
    • JEP 333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)
    • JEP 377: ZGC: A Scalable Low-Latency Garbage Collector (Production)

    View Slide

  6. Preview, Incubator, Experimental
    • 「開発者からのフィードバックが欲しいので試してね」というお試し機能
    • 今後のリリースで変更される可能性がある
    • Preview (JEP 12: Preview Features)
    • 言語、JVM、APIの新機能
    • 完成度: 95%
    • javac--enable-preview --release 21 && java --enable-preview
    • Incubator (JEP 11: Incubator Modules)
    • ある程度大きく、独立した新しいAPI、ツール
    • 完成度: Previewよりも低い場合がある
    • jdk.incubatorモジュール
    • Experimental
    • JVM実装(HotSpot)の新機能、改善(GC、JITなど)
    • 完成度: 25%
    • アプリケーションに支障がある可能性がある
    • java-XX:+UnlockExperimentalVMOptions

    View Slide

  7. 2021
    2022
    2023
    2019
    2020
    2018
    9
    10 11LTS
    14 15
    12 13 16 17LTS
    18 19
    20 21LTS
    Review Recent Java Releases

    View Slide

  8. 2021
    2022
    2023
    2019
    2020
    2018
    9
    10 11LTS
    14 15
    12 13 16 17LTS
    18 19
    20 21LTS
    Review Recent Java Releases ― Number of JEPs
    91
    12 17
    8 5
    17 14
    17 14
    9 7
    7 15

    View Slide

  9. 2021
    2022
    2023
    2019
    2020
    2018
    9
    10 11LTS
    14 15
    12 13 16 17LTS
    18 19
    20 21LTS
    Review Recent Java Releases ― Number of JEPs
    91
    12 17
    8 5
    17 14
    17 14
    9 7
    7 15
    120 75 38

    View Slide

  10. 2021
    2022
    2023
    2019
    2020
    2018
    9
    10 11LTS
    14 15
    12 13 16 17LTS
    18 19
    20 21LTS
    Review Recent Java Releases ― Key features
    ・Var
    ・App CDS
    ・Var for Lambda
    ・Epsilon GC
    ・HTTP Client
    ・java Main.java
    ・JFR
    ・Switch expr
    ・Helpful NPE
    ・Remove CMS
    ・TextBlock
    ・ZGC
    ・Shenandoah
    ・Remove Nashorn
    ・Record
    ・Pattern matching
    for instanceof
    ・jpackage
    ・Move to GitHub
    ・Sealed class
    ・Remove --illegal-access
    ・Simple Web Server
    (jwebserver)
    ・Jigsaw
    ・jshell
    ・New version schema
    (many)

    View Slide

  11. Java 21 JEPs
    • 430: String Templates (Preview)
    • 431: Sequenced Collections
    • 439: Generational ZGC
    • 440: Record Patterns
    • 441: Pattern Matching for switch
    • 442: Foreign Function & Memory API (Third Preview)
    • 443: Unnamed Patterns and Variables (Preview)
    • 444: Virtual Threads
    • 445: Unnamed Classes and Instance Main Methods (Preview)
    • 446: Scoped Values (Preview)
    • 448: Vector API (Sixth Incubator)
    • 449: Deprecate the Windows 32-bit x86 Port for Removal
    • 451: Prepare to Disallow the Dynamic Loading of Agents
    • 452: Key Encapsulation Mechanism API
    • 453: Structured Concurrency (Preview)

    View Slide

  12. Java 21 JEPs
    • Language (Project Amber, etc)
    • 440: Record Patterns
    • 441: Pattern Matching for switch
    • 430: String Templates (Preview)
    • 443: Unnamed Patterns and Variables (Preview)
    • 445: Unnamed Classes and Instance Main Methods (Preview)
    • API
    • 431: Sequenced Collections
    • 452: Key Encapsulation Mechanism API
    • JVM&Runtime
    • 439: Generational ZGC
    • 451: Prepare to Disallow the Dynamic Loading of Agents
    • 449: Deprecate the Windows 32-bit x86 Port for Removal
    • Project Loom
    • 444: Virtual Threads
    • 446: Scoped Values (Preview)
    • 453: Structured Concurrency (Preview)
    • Project Panama
    • 442: Foreign Function & Memory API (Third Preview)
    • 448: Vector API (Sixth Incubator)

    View Slide

  13. Java 21 JEPs
    • Language (Project Amber, etc)
    • 440: Record Patterns
    • 441: Pattern Matching for switch
    • 430: String Templates (Preview)
    • 443: Unnamed Patterns and Variables (Preview)
    • 445: Unnamed Classes and Instance Main Methods (Preview)
    • API
    • 431: Sequenced Collections
    • 452: Key Encapsulation Mechanism API
    • JVM&Runtime
    • 439: Generational ZGC
    • 451: Prepare to Disallow the Dynamic Loading of Agents
    • 449: Deprecate the Windows 32-bit x86 Port for Removal
    • Project Loom
    • 444: Virtual Threads
    • 446: Scoped Values (Preview)
    • 453: Structured Concurrency (Preview)
    • Project Panama
    • 442: Foreign Function & Memory API (Third Preview)
    • 448: Vector API (Sixth Incubator)

    View Slide

  14. Java 21 JEPs
    • Language (Project Amber, etc)
    • 440: Record Patterns
    • 441: Pattern Matching for switch
    • 430: String Templates (Preview)
    • 443: Unnamed Patterns and Variables (Preview)
    • 445: Unnamed Classes and Instance Main Methods (Preview)
    • API
    • 431: Sequenced Collections
    • 452: Key Encapsulation Mechanism API
    • JVM&Runtime
    • 439: Generational ZGC
    • 451: Prepare to Disallow the Dynamic Loading of Agents
    • 449: Deprecate the Windows 32-bit x86 Port for Removal
    • Project Loom
    • 444: Virtual Threads
    • 446: Scoped Values (Preview)
    • 453: Structured Concurrency (Preview)
    • Project Panama
    • 442: Foreign Function & Memory API (Third Preview)
    • 448: Vector API (Sixth Incubator)

    View Slide

  15. 440: Record Patterns
    441: Pattern Matching for switch
    • Pattern Match
    • 式(値)を構造と条件によるマッチングを行い値を取り出す言語機能
    • どこに書けるか
    • どんな構造をdeconstructできるか
    • どんな条件でmachingできるか

    View Slide

  16. 440: Record Patterns
    441: Pattern Matching for switch
    OK NG
    どこに書けるか • instanceof expr
    • Switch condition
    • Variable definition
    • Variable in for loop
    • Method definition
    どんな構造をdeconstructできるか • Type
    • Record
    • Object content
    • Primitive Type
    • Array
    • Collection
    • j.u.Optional
    どんな条件でmatchingできるか • Type
    • Record
    • Object content
    • Primitive Type
    • Enum value
    • Collections

    View Slide

  17. 440: Record Patterns
    441: Pattern Matching for switch
    sealed interface Maybe permits Just, Nothing {}
    record Just(T value) implements Maybe {}
    record Nothing() implements Maybe {}
    Maybe> maybe = ...;
    String str = maybe instanceof Just j ? String.valueOf(j.value())
    : "Nothing";

    View Slide

  18. 440: Record Patterns
    441: Pattern Matching for switch
    sealed interface Maybe permits Just, Nothing {}
    record Just(T value) implements Maybe {}
    record Nothing() implements Maybe {}
    Maybe> maybe = ...;
    switch (maybe) {
    case Just j -> // Pattern for Type in switch cond.
    String.valueOf(j.value());
    case Nothing n -> "Nothing"; // Pattern for Type in switch cond.
    }

    View Slide

  19. 440: Record Patterns
    441: Pattern Matching for switch
    sealed interface Maybe permits Just, Nothing {}
    record Just(T value) implements Maybe {}
    record Nothing() implements Maybe {}
    Maybe> maybe = ...;
    switch (maybe) {
    case Just(var s) -> // Pattern for Record in switch cond.
    String.valueOf(s);
    case Nothing() -> "Nothing"; // Pattern for Record in switch cond.
    }

    View Slide

  20. 440: Record Patterns
    441: Pattern Matching for switch
    sealed interface Maybe permits Just, Nothing {}
    record Just(T value) implements Maybe {}
    record Nothing() implements Maybe {}
    Maybe> maybe = ...;
    switch (maybe) {
    case Just(var s) when s == null ->
    throw new NullPointerException();
    case Just(var s) ->
    String.valueOf(s);
    case Nothing n -> "Nothing"; // Pattern for Type in switch cond.
    case null -> "null"
    }

    View Slide

  21. 440: Record Patterns
    441: Pattern Matching for switch
    sealed interface Maybe permits Just, Nothing {}
    record Just(T value) implements Maybe {}
    record Nothing() implements Maybe {}
    Maybe> maybe = ...;
    switch (maybe) {
    // Pattern for Record matching Type in switch cond.
    case Just(String s) -> "String";
    case Just(Integer n) -> "Integer";
    case Just j -> "Other"; // Pattern for Type in switch cond.
    case Nothing n -> "Nothing"; // Pattern for Type in switch cond.
    }

    View Slide

  22. 440: Record Patterns
    441: Pattern Matching for switch
    sealed interface Maybe permits Just, Nothing {}
    record Just(T value) implements Maybe {}
    record Nothing() implements Maybe {}
    Maybe> maybe = ...;
    switch (maybe) {
    // Pattern for Record matching Record in switch cond.
    case Just(Just(String s)) -> s;
    case Just(Nothing()) -> "Just Nothing";
    case Nothing() -> "Nothing";
    }

    View Slide

  23. 440: Record Patterns
    441: Pattern Matching for switch
    sealed interface FList permits Empty, Cons {}
    record Empty() implements FList {}
    record Cons(T head, FList tail) implements FList {}
    int size(FList> list) {
    return switch (list) {
    case Cons(var head, var tail) -> size(tail) + 1;
    case Empty() -> 0;
    };
    }

    View Slide

  24. 440: Record Patterns
    441: Pattern Matching for switch
    enum Action {
    SHRINK, EXPAND
    }
    Maybe action = ...;
    size += switch (action) {
    case Just(SHRINK) -> -10; // NG, cannot match with Enum value
    case Just(EXPAND) -> 10; // NG, cannot match with Enum value
    case Nothing() -> 0;
    }

    View Slide

  25. 440: Record Patterns
    441: Pattern Matching for switch
    enum Action {
    SHRINK, EXPAND
    }
    Maybe action = ...;
    size += switch (action) {
    case Just(var a) when a == Action.SHRINK -> -10;
    case Just(var a) when a == Action.EXPAND -> 10;
    case Just j -> throw new ISE("Added new enum value to Action");
    case Nothing() -> 0;
    }

    View Slide

  26. 440: Record Patterns
    441: Pattern Matching for switch
    enum Action {
    SHRINK, EXPAND
    }
    Maybe action = ...;
    size += switch (action) {
    case Just(var a) ->
    switch (a) {
    case SHRINK -> -10;
    case EXPAND -> 10;
    };
    case Nothing() -> 0;
    }

    View Slide

  27. Java 21 JEPs
    • Language (Project Amber, etc)
    • 440: Record Patterns
    • 441: Pattern Matching for switch
    • 430: String Templates (Preview)
    • 443: Unnamed Patterns and Variables (Preview)
    • 445: Unnamed Classes and Instance Main Methods (Preview)
    • API
    • 431: Sequenced Collections
    • 452: Key Encapsulation Mechanism API
    • JVM&Runtime
    • 439: Generational ZGC
    • 451: Prepare to Disallow the Dynamic Loading of Agents
    • 449: Deprecate the Windows 32-bit x86 Port for Removal
    • Project Loom
    • 444: Virtual Threads
    • 446: Scoped Values (Preview)
    • 453: Structured Concurrency (Preview)
    • Project Panama
    • 442: Foreign Function & Memory API (Third Preview)
    • 448: Vector API (Sixth Incubator)

    View Slide

  28. 430: String Templates
    • 文字列リテラル内に記載されたその言語の式を評価し、文字列等を作る構文
    • Scala: s"$x plus $y equals ${x + y}"
    • Kotlin: "$x plus $y equals ${x + y}"
    • C#: $"{x} plus {y} equals {x + y}"
    • Ruby: "#{x} plus #{y} equals #{x + y}"
    • Python: f"{x} plus {y} equals {x + y}"
    • 各言語の違い
    • 通常の文字列リテラルと区別するか
    • 文字列内の式を区別する文字
    • 検証や文字列以外への変換をユーザ定義できるか (Scala)

    View Slide

  29. 430: String Templates
    • String Templatesは危険?
    • 一般にどんな言語機能も良くない使い方ができてしまう
    • 便利であればあるほど、うっかりやってしまう
    • var query = "SELECT * FROM users WHERE uname = '$uname'"
    • JSON object、Regex object、SQL objectなどに変換できたら便利で安全
    • →検証や文字列以外への変換をユーザ定義できるか
    • Scala
    • そしてJavaも

    View Slide

  30. 430: String Templates
    • String s = STR."\{x} plus \{y} equals \{x + y}"
    • String Template内の式を区別する文字: ¥{...}
    • ¥{は既存の文字列リテラルでは使われていない
    • "¥¥{"
    • $,#は使われている
    • 通常の文字列リテラルで¥{x}を書くとエラー
    • 検証や文字列以外への変換をユーザ定義できる
    • StringTemplate + StringTemplate.Processor

    View Slide

  31. 430: String Templates
    •StringTemplateリテラルとStringTemplate.Processorを組み合わせて使う
    STR."\{x} plus \{y} equals \{x + y}"
    •StringTemplate.STR: StringTemplate.Processor
    •"\{x} plus \{y} equals \{x + y}"
    StringTemplate.of(
    fragments = List.of(""," plus "," equals ", "")
    values = List.of( x, y, x + y)
    )
    •StringTemplate.STR.process(StringTemplate.of(...))
    •bytecodeレベルではindyを使って最適化している

    View Slide

  32. 430: String Templates
    • StringTemplate.Processorは各々で定義できる
    • R process(StringTemplate st) throws E;
    • R: 文字列テンプレート式の値の型
    • E: 文字列テンプレート式によって発生する例外
    • stの検証と値の変換のみに注力するべき
    • DBアクセスなどはオススメされない
    • 例
    • StringTemplate.RAW: StringTemplate.Processor
    • FormatProcessor.FMT
    • LocalizationProcessor(Locale locale)
    • JSON: StringTemplate.Processor
    • SQL: StringTemplate.Processor
    • C: StringTemplate.Processor, CNFException>

    View Slide

  33. Java 21 JEPs
    • Language (Project Amber, etc)
    • 440: Record Patterns
    • 441: Pattern Matching for switch
    • 430: String Templates (Preview)
    • 443: Unnamed Patterns and Variables (Preview)
    • 445: Unnamed Classes and Instance Main Methods (Preview)
    • API
    • 431: Sequenced Collections
    • 452: Key Encapsulation Mechanism API
    • JVM&Runtime
    • 439: Generational ZGC
    • 451: Prepare to Disallow the Dynamic Loading of Agents
    • 449: Deprecate the Windows 32-bit x86 Port for Removal
    • Project Loom
    • 444: Virtual Threads
    • 446: Scoped Values (Preview)
    • 453: Structured Concurrency (Preview)
    • Project Panama
    • 442: Foreign Function & Memory API (Third Preview)
    • 448: Vector API (Sixth Incubator)

    View Slide

  34. 443: Unnamed Patterns and Variables (Preview)
    • 不必要な宣言を_で代用できる
    • パターン
    • 変数
    • try-with-resources
    • for-loop
    • catchした例外
    • ラムダのパラメーター
    try (var _ = newTracer()) {
    if (getEntity(id) instanceof Entity(_, var kind)) {
    // Entity(var _, var kind)もOK
    map.computeIfAbsent(kind, _ -> new ArrayList<>())
    .add(id);
    }
    } catch (IOE _) {}

    View Slide

  35. 445: Unnamed Classes and Instance Main
    Methods (Preview)
    $ cat Main.java
    import static java.lang.System.*;
    final String NAME = "Java"; // static
    void sayHello() {
    Util.print(STR."Hello \{NAME}");
    // Main.Util.print(...)もOK
    }
    void main() { // String... argsは省略可 (クラス内に宣言した場合も)
    sayHello();
    }
    class Util { // Main.Util
    static void print(String msg) {
    out.println(msg);
    }
    }
    $ javac … Main.java
    $ ls *.class
    Main.class Main$Util.class

    View Slide

  36. Java 21 JEPs
    • Language (Project Amber, etc)
    • 440: Record Patterns
    • 441: Pattern Matching for switch
    • 430: String Templates (Preview)
    • 443: Unnamed Patterns and Variables (Preview)
    • 445: Unnamed Classes and Instance Main Methods (Preview)
    • API
    • 431: Sequenced Collections
    • 452: Key Encapsulation Mechanism API
    • JVM&Runtime
    • 439: Generational ZGC
    • 451: Prepare to Disallow the Dynamic Loading of Agents
    • 449: Deprecate the Windows 32-bit x86 Port for Removal
    • Project Loom
    • 444: Virtual Threads
    • 446: Scoped Values (Preview)
    • 453: Structured Concurrency (Preview)
    • Project Panama
    • 442: Foreign Function & Memory API (Third Preview)
    • 448: Vector API (Sixth Incubator)

    View Slide

  37. 431: Sequenced Collections
    • List
    • LinkedHashSet
    • SortedSet
    • NavigableSet
    • TreeSet
    • Deque
    • BlockingDeque
    • LinkedHashMap
    • SortedMap
    • NavigableMap
    • TreeMap

    View Slide

  38. 431: Sequenced Collections
    • List
    • LinkedHashSet
    • SortedSet
    • NavigableSet
    • TreeSet
    • Deque
    • BlockingDeque
    • LinkedHashMap
    • SortedMap
    • NavigableMap
    • TreeMap
    • 先頭の要素
    • 末尾の要素

    View Slide

  39. 431: Sequenced Collections
    • List: get(0), get(size()-1)
    • LinkedHashSet
    • SortedSet: first(), last()
    • NavigableSet: first(), last(), pollFirst(), pollLast()
    • TreeSet
    • Deque: getFirst(), getLast()
    • BlockingDeque
    • LinkedHashMap
    • SortedMap: firstKey(), lastKey()
    • NavigableMap: firstEntry(), lastEntry(), pollFirstEntry(), pollLastEntry()
    • TreeMap
    • 先頭の要素
    • 末尾の要素

    View Slide

  40. 431: Sequenced Collections
    • SequencedCollection
    extends Collection
    • E getFirst()
    • E getLast()
    • void addFirst(E) throws USE
    • void addLast(E) throws USE
    • E removeFirst(E) throws USE
    • E removeLast(E) throws USE
    • SequencedCollection reversed()
    • SequencedSet
    extends Set, SequenecdCollection
    • SequencedSet reversed()
    • SequencedMap
    extends Map
    • Entry firstEntry()
    • Entry lastEntry()
    • void putFirstEntry(Entry) throws USE
    • void putLastEntry(Etnry) throws USE
    • Entry pollFirstEntry() throws USE
    • Entry pollLastEntry() throws USE
    • SequencedMap reversed()
    • SequencedSet> sequencedEntrySet()
    • SequencedSet sequencedKeySet()
    • SequencedCollection sequencedValues()

    View Slide

  41. 431: Sequenced Collections
    • SequencedCollection
    extends Collection
    • E getFirst()
    • E getLast()
    • void addFirst(E) throws USE
    • void addLast(E) throws USE
    • E removeFirst(E) throws USE
    • E removeLast(E) throws USE
    • SequencedCollection reversed()
    • SequencedSet
    extends Set, SequenecdCollection
    • SequencedSet reversed()
    • SequencedMap
    extends Map
    • Entry firstEntry()
    • Entry lastEntry()
    • void putFirstEntry(Entry) throws USE
    • void putLastEntry(Etnry) throws USE
    • Entry pollFirstEntry() throws USE
    • Entry pollLastEntry() throws USE
    • SequencedMap reversed()
    • SequencedSet> sequencedEntrySet()
    • SequencedSet sequencedKeySet()
    • SequencedCollection sequencedValues()

    View Slide

  42. 431: Sequenced Collections
    • SequencedCollection
    extends Collection
    • E getFirst()
    • E getLast()
    • void addFirst(E) throws USE
    • void addLast(E) throws USE
    • E removeFirst(E) throws USE
    • E removeLast(E) throws USE
    • SequencedCollection reversed()
    • SequencedSet
    extends Set, SequenecdCollection
    • SequencedSet reversed()
    • SequencedMap
    extends Map
    • Entry firstEntry()
    • Entry lastEntry()
    • void putFirstEntry(Entry) throws USE
    • void putLastEntry(Etnry) throws USE
    • Entry pollFirstEntry() throws USE
    • Entry pollLastEntry() throws USE
    • SequencedMap reversed()
    • SequencedSet> sequencedEntrySet()
    • SequencedSet sequencedKeySet()
    • SequencedCollection sequencedValues()

    View Slide

  43. Java 21 JEPs
    • Language (Project Amber, etc)
    • 440: Record Patterns
    • 441: Pattern Matching for switch
    • 430: String Templates (Preview)
    • 443: Unnamed Patterns and Variables (Preview)
    • 445: Unnamed Classes and Instance Main Methods (Preview)
    • API
    • 431: Sequenced Collections
    • 452: Key Encapsulation Mechanism API
    • JVM&Runtime
    • 439: Generational ZGC
    • 451: Prepare to Disallow the Dynamic Loading of Agents
    • 449: Deprecate the Windows 32-bit x86 Port for Removal
    • Project Loom
    • 444: Virtual Threads
    • 446: Scoped Values (Preview)
    • 453: Structured Concurrency (Preview)
    • Project Panama
    • 442: Foreign Function & Memory API (Third Preview)
    • 448: Vector API (Sixth Incubator)

    View Slide

  44. 452: Key Encapsulation Mechanism API
    • 鍵カプセル化メカニズム(KEM; Key Encapslation Mechanism)をJava APIに
    • ハイブリッド暗号のための仕様、暗号化方式
    • 公開鍵暗号: 安全に鍵交換が可能、性能が課題
    • 共通鍵暗号: 性能は良い、鍵交換が課題
    • ハイブリッド暗号:公開鍵暗号を用い共通鍵を共有し、平文を共通鍵で暗号化する
    • 耐量子暗号ではKEMが標準的に
    • NISTは公募する耐量子暗号にKEMを求めている
    • CRYSTALS-Kyber

    View Slide

  45. 452: Key Encapsulation Mechanism API
    ※ABC, ABC-KEMはアルゴリズム名 (RSA, RSA-KEM)など
    OpenJDKではDHKEM (ディフィー・ヘルマン鍵共有)がサポートされている
    // Alice
    KEM kemR = KEM.getInstance("ABC-KEM");
    var g = KeyPairGenerator.getInstance("ABC");
    var kp = g.generateKeyPair();
    publishKey(kp.getPublic());
    var em = receiveBytes();
    var params = receiveBytes();
    var algParams = AlgorithmParameters.getInstance("ABC-KEM");
    algParams.init(params);
    var spec = algParams.getParameterSpec(ABCKEMParameterSpec.class);
    KEM.Decapsulator d = kem.newDecapsulator(kp.getPrivate(), spec);
    SecretKey key = d.decapsulate(em);
    // Bob
    KEM kem = KEM.getInstance("ABC-KEM");
    PublicKey pk = retrieveKey();
    var spec = new ABCKEMParameterSpec(...);
    KEM.Encapsulator e = kem.newEncapsulator(pk, spec, null);
    KEM.Encapsulated enc = e.encapsulate();
    sendBytes(enc.encapsulation());
    sendBytes(enc.params());
    SecretKey key = enc.key();

    View Slide

  46. Java 21 JEPs
    • Language (Project Amber, etc)
    • 440: Record Patterns
    • 441: Pattern Matching for switch
    • 430: String Templates (Preview)
    • 443: Unnamed Patterns and Variables (Preview)
    • 445: Unnamed Classes and Instance Main Methods (Preview)
    • API
    • 431: Sequenced Collections
    • 452: Key Encapsulation Mechanism API
    • JVM&Runtime
    • 439: Generational ZGC
    • 451: Prepare to Disallow the Dynamic Loading of Agents
    • 449: Deprecate the Windows 32-bit x86 Port for Removal
    • Project Loom
    • 444: Virtual Threads
    • 446: Scoped Values (Preview)
    • 453: Structured Concurrency (Preview)
    • Project Panama
    • 442: Foreign Function & Memory API (Third Preview)
    • 448: Vector API (Sixth Incubator)

    View Slide

  47. 451: Prepare to Disallow the Dynamic Loading
    of Agents
    • Java Agent (Java 5)
    • 実行時に動的にクラスの挙動を変更できる
    • 起動時に--javaagent--agentlibで明示的に指定
    • 無害なモニタリングなどの用途で導入された
    • アスペクト指向やJDKの挙動を変えるのに使いだされた
    • Attach API (Java 6)
    • 実行中のJavaプロセスに接続して監視などを行える
    • Java Agentを動的にロードできてしまう
    • Jigsaw (Java 9)
    • JDKやライブラリに強力なカプセル化を導入
    • Java Agentを使ってそれを迂回できてしまう

    View Slide

  48. 451: Prepare to Disallow the Dynamic Loading
    of Agents
    • Attach APIを使ってJava Agentを動的にロードすると警告
    • 将来的にはデフォルトでは禁止に
    • --javaagentで静的にロード:OK
    • 動的にロードする場合:-XX:+EnableDynamicAgentLoading
    • Java AgentをロードしないAttachAPIを使用するツール:影響を受けない
    • jcmd
    • jconsole
    • ...
    WARNING: A {Java,JVM TI} agent has been loaded dynamically (file:/u/bob/agent.jar)
    WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
    WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
    WARNING: Dynamic loading of agents will be disallowed by default in a future release

    View Slide

  49. Java 21 JEPs
    • Language (Project Amber, etc)
    • 440: Record Patterns
    • 441: Pattern Matching for switch
    • 430: String Templates (Preview)
    • 443: Unnamed Patterns and Variables (Preview)
    • 445: Unnamed Classes and Instance Main Methods (Preview)
    • API
    • 431: Sequenced Collections
    • 452: Key Encapsulation Mechanism API
    • JVM&Runtime
    • 439: Generational ZGC
    • 451: Prepare to Disallow the Dynamic Loading of Agents
    • 449: Deprecate the Windows 32-bit x86 Port for Removal
    • Project Loom
    • 444: Virtual Threads
    • 446: Scoped Values (Preview)
    • 453: Structured Concurrency (Preview)
    • Project Panama
    • 442: Foreign Function & Memory API (Third Preview)
    • 448: Vector API (Sixth Incubator)

    View Slide

  50. 449: Deprecate the Windows 32-bit x86 Port
    for Removal
    • Windows 10
    • 32 bit arch.をサポートする最後のWindows
    • 2025/10/14サポート終了予定
    • Windows 32-bit x86向けのJDKのサポートを将来終了するための準備

    View Slide

  51. Java 21 JEPs
    • Language (Project Amber, etc)
    • 440: Record Patterns
    • 441: Pattern Matching for switch
    • 430: String Templates (Preview)
    • 443: Unnamed Patterns and Variables (Preview)
    • 445: Unnamed Classes and Instance Main Methods (Preview)
    • API
    • 431: Sequenced Collections
    • 452: Key Encapsulation Mechanism API
    • JVM&Runtime
    • 439: Generational ZGC
    • 451: Prepare to Disallow the Dynamic Loading of Agents
    • 449: Deprecate the Windows 32-bit x86 Port for Removal
    • Project Loom
    • 444: Virtual Threads
    • 446: Scoped Values (Preview)
    • 453: Structured Concurrency (Preview)
    • Project Panama
    • 442: Foreign Function & Memory API (Third Preview)
    • 448: Vector API (Sixth Incubator)

    View Slide

  52. Project Loom
    • Virtual Threads + 限定継続をJavaに導入
    • IO待ちの多い同期処理をスケーラブルに並列実行可能
    • マルチスレッドに関連した処理を簡潔、明瞭に行えるよう改良
    • 446: Scoped Values (Preview)
    • Thread Local VariableのPainpointsを改良
    • 453: Structured Concurrency (Preview)
    • 並列実行した処理の結果待ちを簡単に

    View Slide

  53. DB
    DB
    DB
    DB
    512 threads / App
    50%tile latency = 10ms
    request = 5000 rps / App
    LB
    LB
    App
    App
    App
    App

    View Slide

  54. DB
    DB
    DB
    DB
    512 threads / App
    50%tile latency = 10ms
    request = 5000 rps / App
    LB
    LB
    App
    App
    App
    App

    View Slide

  55. Metrics (平常時)

    View Slide

  56. DB
    DB
    DB
    DB
    512 threads / App
    50%tile latency = 10ms
    request = 5000 rps / App
    LB
    LB
    App
    App
    App
    App

    View Slide

  57. DB
    DB
    DB
    DB
    512 threads / App
    50%tile latency = 10ms
    request = 5000 rps / App
    LB
    LB
    App
    App
    App
    App
    DB failure!!
    95%tile latency = 3000ms

    View Slide

  58. Metrics (95%tile悪化時)

    View Slide

  59. Java Thread = OS Thread
    Thread 1 Thread 2 Thread 3
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    unpack
    response
    Queue

    View Slide

  60. Thread 2 Thread 3
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    3s
    unpack
    response
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    3s
    unpack
    response
    validate
    DB
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    3s
    Queue
    10msで終わるのに
    もう1秒も待ってる
    Java Thread = OS Thread
    Thread 1

    View Slide

  61. IO Event handler thread
    validate
    validate
    validate
    Application thread
    unpack
    response
    unpack
    response
    unpack
    response
    Application thread
    IO Event
    handler
    loop
    DB request + callback
    Run callback
    DB request + callback
    Run callback
    DB request + callback
    Run callback
    DB
    DB
    DB
    validate
    DB request + callback DB
    unpack
    response

    View Slide

  62. Non blocking IOと非同期処理のPainpoints
    • JavaだとCallback hell
    • ラムダ式、メソッドチェーン
    • try-catchとの相性が最悪
    • IOを呼び出したスレッドと違うスレッドで後続の処理
    • スレッドセーフティ
    • プログラムの挙動がわかりにくく、調査やデバッグが難しい
    • Stack traceなど
    • (キャッシュ効率↓)
    • 慣れればそんなに辛くはないが、それでも同期処理よりは難しい

    View Slide

  63. Thread 2 Thread 3
    validate
    DB
    access
    unpack
    response
    validate
    DB
    access
    Virtual Thread
    Thread 1
    Java Thread = OS Thread
    Carrier Thread
    DB
    access
    3s
    validate
    DB done? or yield()
    validate
    DB done? or yield()
    unpack
    response
    unpack
    response
    validate
    DB
    access
    unpack
    response
    validate
    DB done? or yield()
    DB done? or yield()
    unpack
    response
    unpack
    response

    View Slide

  64. Metrics (95%tile悪化時 + Virtual Thread)

    View Slide

  65. Metrics (95%tile悪化時, Before/After)

    View Slide

  66. Metrics (95%tile悪化時, Before/After)

    View Slide

  67. Platform ThreadとVirtual Thread
    CPU
    1
    CPU
    2
    CPU
    3
    CPU
    4
    Platform
    Thread
    Platform
    Thread
    Platform
    Thread
    Platform
    Thread
    OS
    OS
    Thread
    OS
    Thread
    OS
    Thread
    OS
    Thread
    Java Runtime
    Java application
    Carrier Threads
    ForkJoinPool
    Virtual
    Thread
    Virtual
    Thread

    View Slide

  68. Virtual Thread
    • 任意のCarrier Threadで実行される
    • yield or 終了するまでCarrier Threadを専有する
    • タイムシェアリングは行われない
    • Thread.startVirtualThread(Runnable): void
    • Thread.ofVirtual()
    • .factory(): ThreadFactory
    • .start(Runnable): Thread
    • .unstarted(Runnable): Thread
    • Executors.newVirtualThreadPerTaskExecutor(): ExecutorService
    • Tomcat
    • org.apache.catalina.core.StandardVirtualThreadExecutor

    View Slide

  69. yield
    • 処理を中断して、Carrier Threadの専有を解く
    • 明示的に呼び出す必要がある
    • 基本的にはライブラリが呼び出している
    • sleep, await, lock, File IO, Socket IO, NIO, ...
    • 限定継続のreset
    • shiftはJava (Virtual Thread scheduler)が呼び出す
    • Thread.yield()

    View Slide

  70. Virtual Threadの設定 (System property)
    • jdk.virtualThreadScheduler.parallelism
    • 基準となる並列度 (Carrier Thread数)
    • Default: Runtime.getRuntime().availableProcessors()
    • jdk.virtualThreadScheduler.maxPoolSize
    • プールされる最大のCarrier Thread数
    • Default: max(parallelism, 256)
    • Carrier Threadがブロックされたときに、Carrier Threadを増やせる?
    • 挙動を確認できず
    • jdk.virtualThreadScheduler.minRunnable
    • 最小のCarrierThread数
    • Default: max(parallelism / 2, 1)

    View Slide

  71. Virtual Threadがあれば非同期処理は不要?
    • VT+同期処理、非同期処理を組み合わせることが重要
    • 非同期処理: 低レスポンスタイム
    Thread.startVirtualThread(() -> {
    var aFuture = readFromDB1();
    var bFuture = readFromDB2();
    var cFuture = readFromMicroservice();
    var a = aFuture.get();
    // ...
    });
    • → JEP 453: Structured Concurrency

    View Slide

  72. Virtual Threadの注意点
    • Virtual Threadをプールしない
    • yieldを行わない処理を長時間実行しない
    • Carrier Threadを専有して他のVTの実行を阻害
    • Platform Threadで実行してawait
    • Thread.yield()を呼ぶ
    • 長時間のsynchronized、Object.wait()、nativeメソッド
    • yieldを行わない
    • レイテンシが上がる可能性
    • アプリケーションのシャットダウンに注意
    • Virtual Threadはdaemon thread
    • Carrier ThreadのExecutorを変更できない
    • モニタリング、リソースの分離、schedulingのカスタマイズできない
    • リフレクションを使えば変更可能
    • jstackではVTのスタックトレースを取得できない
    • jcmd Thread.dump_to_file -format=json

    View Slide

  73. Java 21まとめ
    • Pattern Matchingは着実に進歩
    • その他のPreview言語機能もいい感じ
    • ついにVirtualThreadがGA
    • Thread、ExecutorServiceから扱えるので既存の資産を再利用できる
    • 注意点が多いのでプロダクション適用時は要確認
    • Java 22は2024/03/19リリース予定
    • まだまだ進化するJava、今すぐダウンロー
    ド!

    View Slide

  74. おまけ
    void startSendRequests() {
    var executor = newFixedThreadPool(500);
    for (int i = 0; i < 500; i++) {
    executor.submit(() -> {
    while (true) {
    handleRequest();
    try {
    Thread.sleep(100);
    } catch (InterruptedException _) {}
    }
    });
    }
    }
    ExecutorService serverThreads = newFixedThreadPool(512);
    ExecutorService serverThreads = newVirtualThreadPerTaskExecutor();
    void handleRequest() {
    queueSize.incrementAndGet();
    long startNano = System.nanoTime();
    serverThreads.submit(() -> {
    queueSize.decrementAndGet();
    activeThreads.incrementAndGet();
    accessToDB();
    long endNano = System.nanoTime();
    totalResponseTime.getAndAdd(endNano - startNano);
    responseTimes.add(endNano - startNano);
    activeThreads.decrementAndGet();
    requestCount.incrementAndGet();
    return null;
    });
    }
    void accessToDB() {
    boolean dbSuccess = !databaseFailure
    || ThreadLocalRandom.current().nextDouble() < 0.95;
    try {
    if (dbSuccess) {
    Thread.sleep(10);
    } else {
    Thread.sleep(3_000);
    }
    } catch (InterruptedException _) {}
    }

    View Slide

  75. void main() {
    for (int t = 0; t < 100; t++) {
    int id = t;
    runCountPrimeNumberAsVirtualThread(id, false);
    // runCountPrimeNumberAsVirtualThread(id, true);
    // runCountPrimeNumber2AsPlatformThreadFromVirtualThread(id);
    long startFasterIO = System.nanoTime();
    Thread.startVirtualThread(() -> {
    System.out.println(STR."Faster IO (\{100+id})");
    try { Thread.sleep(100); } catch (Exception _) {}
    long endFasterIO = System.nanoTime();
    long duration = TimeUnit.NANOSECONDS.toMillis(end - start);
    System.out.println(STR."Faster IO (\{100+id}): \{duration}ms");
    });
    }
    // await jobs
    }
    void runCountPrimeNumberAsVirtualThread(int id, boolean yield) {
    long start = System.nanoTime();
    Thread.startVirtualThread(() -> {
    int target = ThreadLocalRandom.current().nextInt(500_000);
    println(STR."COMP (\{id}): 2~\{target}");
    int count = countPrimeNumber(target, yield);
    long end = System.nanoTime();
    long duration = TimeUnit.NANOSECONDS.toMillis(end - start);
    println(STR."COMP (\{id}): \{duration}ms");
    });
    }
    ExecutorService e = Executors.newFixedThreadPool(100);
    void runCountPrimeNumber2AsPlatformThreadFromVirtualThread(int id) {
    long start = System.nanoTime();
    Thread.startVirtualThread(() -> {
    int target = ThreadLocalRandom.current().nextInt(500_000);
    println(STR."COMP (\{id}): 2~\{target}");
    try {
    int count = e.submit(() -> countPrimeNumber(target, false)).get();
    long end = System.nanoTime();
    long duration = TimeUnit.NANOSECONDS.toMillis(end - start);
    println(STR."COMP (\{id}): \{duration}ms");
    } catch (Exception _) {}
    });
    }
    int countPrimeNumber(int target, boolean yield) {
    int count = 0;
    outer:
    for (int i = 2; i <= target; i++) {
    // Intentionally slow implementation
    for (int j = 2; j < i; j++) {
    if (i % j == 0) {
    continue outer;
    }
    }
    count++;
    if (yield) {
    Thread.yield();
    }
    }
    return count;
    }

    View Slide