Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Virtual Threadの動作と効果的な使い方

Yuichi.Sakuraba
October 20, 2023
280

Virtual Threadの動作と効果的な使い方

2023.10.20 Javaコミュ@福岡
Java 21リリースイベント@福岡 発表資料

Yuichi.Sakuraba

October 20, 2023
Tweet

Transcript

  1. Virtual Threadの動作と効果的な使い方
    櫻庭 祐一
    Java in the Box

    View full-size slide

  2. 3 分でわかる Virtual Threads
    JVM が管理する軽量スレッド
    Fiber
    他言語でいうところの
    スループット向上が目的
    I/Oを多く含むシステムで効果的
    応答時間はちょっとだけ悪化
    従来のスレッドと使い方は同じ
    使用上の注意点はある

    View full-size slide

  3. 導入の背景
    Agenda
    応答時間とスループット
    動作原理
    なぜスループットが向上するのか
    効果的な使い方
    ユースケースをもとに

    View full-size slide

  4. 導入の背景
    歴史的経緯とともに

    View full-size slide

  5. Performance
    応答時間
    1 タスクを処理する時間
    スループット
    単位時間当たりのタスク処理数
    応答時間 スループット
    スループット 応答時間




    View full-size slide

  6. Performance
    応答時間
    1 タスクを処理する時間
    スループット
    単位時間当たりのタスク処理数
    応答時間 スループット
    スループット 応答時間




    応答時間重視 : 統計処理、データ解析、機械学習
    スループット重視 : アプリケーション、業務システム
    Web

    View full-size slide

  7. スループットを向上させるには
    タスクごとにスレッドを割りつけ Thread per Task/Request
    Threadの切替 : スレッドのコンテキストスイッチ
    OS
    Threadオブジェクト生成: 重い & メモリ消費大
    重い & メモリ消費大
    問題点
    スレッドが増加すると 応答速度悪化
    スループット頭打ち
    OutOfMemoryEerror

    View full-size slide

  8. 業務タスクの特徴
    Comp. I/O C I/O I/O
    C C
    通信、
    DBアクセスなど I/O処理が多い
    I/O処理は計算処理に対して多大な時間を要する
    I/Oの待ち時間が長い
    その中でも
    I/O待ちの間 CPUが遊んでしまう
    I/O待ちの間に他の処理を行いたい

    View full-size slide

  9. Solution #1 非同期処理
    CompletableFuture
    Reactive Programming
    ex. Spring WebFlux
    Oracle Helidon SE
    非同期処理を関数で記述
    }
    処理を非同期実行することで
    スループット向上
    I/O
    とはいうものの
    従来の逐次的な記述と考え方が異なる ...
    例外処理が ...
    デバッグが ...

    View full-size slide

  10. 従来の逐次的な記述で
    例外処理をあつかいやすく
    デバッグもやりやすいままで
    スループットを向上させたい
    しかも
    生成コストやメモリ消費が少なく
    コンテキストスイッチを軽くしたい
    Virtual Thread

    View full-size slide

  11. 動作原理
    なぜスループットが向上するのか

    View full-size slide

  12. Virtual Threads
    Platform Threadとタスクの仲介
    Platform Thread
    タスクからは と区別がつかない
    Platform Thread にマウントして実行
    Carrier Thread
    マウントしたスレッドを と呼ぶ
    積極的なコンテキストスイッチ
    限定継続を導入してコンテキストスイッチの高速化
    Work-Stealingによるスレッドスケジューリング
    一貫性のあるスタックトレース
    Carrier Threadが変わってもスタックトレースが切れない

    View full-size slide

  13. Platform Thread Platform Thread
    ......
    Virtual Thread
    Task
    Instantiation

    View full-size slide

  14. Platform Thread Platform Thread
    ......
    Virtual Thread
    Task
    Mount

    View full-size slide

  15. Platform Thread Platform Thread
    ......
    Virtual Thread
    Task
    I/O Wait

    View full-size slide

  16. Platform Thread Platform Thread
    ......
    Virtual Thread
    Task
    Unmount

    View full-size slide

  17. Platform Thread Platform Thread
    ......
    Virtual Thread
    Task I/O Interrupt

    View full-size slide

  18. Platform Thread Platform Thread
    ......
    Virtual Thread
    Task
    Mount

    View full-size slide

  19. Platform Thread Platform Thread
    ......
    Virtual Thread
    Task
    I/O待ち時間の活用による大幅なスループット向上
    頻繁なコンテキストスイッチによる応答時間の悪化

    View full-size slide

  20. Platform Thread Platform Thread
    ......
    Virtual Thread
    Task
    public int read(ByteBuffer buf) throws IOException {
    ...
    readLock.lock();
    try {
    ...
    configureSocketNonBlockingIfVirtualThread();
    n = IOUtil.read(fd, buf, -1, nd);
    if (blocking) {
    while (IOStatus.okayToRetry(n) && isOpen()) {
    park(Net.POLLIN);
    n = IOUtil.read(fd, buf, -1, nd);
    }
    }
    ...
    sun.nio.ch.SocketChannelImpl

    View full-size slide

  21. void park() {
    ...
    boolean yielded = false;
    setState(PARKING);
    try {
    yielded = yieldContinuation();
    } finally {
    ...
    }
    ...
    }
    java.lang.VirtualThread
    private boolean yieldContinuation() {
    ...
    unmount();
    try {
    return Continuation.yield(VTHREAD_SCOPE);
    } finally {
    mount();
    ...
    }
    }
    限定継続

    View full-size slide

  22. 効果的な使い方
    ユースケースをもとに

    View full-size slide

  23. Virtual Threadsの使い方
    ExecutorServiceを介して利用する
    Executors.newVirtualThreadPerTaskExecutor()
    Executors.newThreadPerTaskExecutor(
    Thread.ofVirtual().factory())
    or
    Virtual Threadの直接生成も可能だが、基本はやらない
    ExecutorServiceを定義する場合だけ
    独自の
    ExecutorServiceはJava 19からAutoClosable

    View full-size slide

  24. Virtual Threadsの使い方
    try (var pool
    = Executors.newVirtualThreadPerTaskExecutor()) {
    Runnable task = ...;
    pool.submit(task);
    }

    View full-size slide

  25. VT 使いたい
    Y
    FWを使ってる ?
    VT使う必要なし
    WebFluxなどのリアクティブ系
    or CompletableFutureゴリゴリ書ける
    Spring Boot, Jakarta EE など
    FWの対応待ち
    その他 使ってない
    or

    View full-size slide

  26. VT使う必要なし
    or CompletableFutureゴリゴリ書ける
    Spring Boot, Jakarta EE など
    FWの対応待ち
    その他 使ってない
    or
    ボトルネックは?
    データ量 / 計算量 ParallelStream
    Fork/Join FW
    Vector API
    File
    Memory Map
    DB
    通信 /
    VirtualThread

    View full-size slide

  27. スレッドの注意点 Virtual Threads
    特に
    synchronizedをなるべく使わないようにする
    1.
    synchronized = モニタロック
    リソースへのアクセスを 1 つのスレッドだけに限定
    他のスレッドをブロックする
    ボトルネックになりやすい
    Virtual Threadでは Carrier Threadをブロックしてしまう

    View full-size slide

  28. スレッドの注意点 Virtual Threads
    特に
    synchronized を使わないようにするには
    イミュータブルクラスの活用
    record 型の利用
    状態が変化しなければ複数スレッドからもアクセス可
    処理結果の受け渡しがある場合 Callableを使う
    どうしてもロックが必要であれば
    synchronizedではなくReentrantLock クラスを使う
    java.util.concurrent.locksにロッククラスあり
    他にも

    View full-size slide

  29. スレッドの注意点 Virtual Threads
    特に
    ThreadLocal を使わない
    2.
    ThreadLocal はミュータブル & ライフタイムが不明確
    Virtual Threads ThreadLocalをサポートしているが

    スケールしないためボトルネック化
    ScopedValueで代用する
    Java 21 Preview JEP
    では
    ただし
    FWが ThreadLocal を使っている場合
    対応してくれるまで待ちましょう

    View full-size slide

  30. スレッドの注意点 Virtual Threads
    特に
    スレッドを使いまわさない
    3.
    Virtual Threadsは使い捨て
    ExecutorService
    スレッドのプールは にまかせる
    タスクを記述することに集中しよう
    クラスの
    4. Thread APIをもう 1 度チェック
    @Deprecated(forRemoval=true)なメソッド
    stop, suspend, resumeなど

    View full-size slide

  31. Conclusion
    Virtual Threadsによりスループットが向上
    I/Oの待ち時間を有効活用
    Virtual Threadsは従来のスレッドを同じ使い方
    使用時の注意点を把握する
    FWで Virtual Threads がサポートされるのを楽しみに待つ

    View full-size slide