Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

Performance 応答時間 1 タスクを処理する時間 スループット 単位時間当たりのタスク処理数 応答時間 スループット スループット 応答時間 → → → → 応答時間重視 : 統計処理、データ解析、機械学習 スループット重視 : アプリケーション、業務システム Web

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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 例

Slide 21

Slide 21 text

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(); ... } } 限定継続

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

スレッドの注意点 Virtual Threads 特に ThreadLocal を使わない 2. ThreadLocal はミュータブル & ライフタイムが不明確 Virtual Threads ThreadLocalをサポートしているが は スケールしないためボトルネック化 ScopedValueで代用する Java 21 Preview JEP では ただし FWが ThreadLocal を使っている場合 対応してくれるまで待ちましょう

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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