Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JEP 480: Structured Concurrency
Search
Aya Ebata
September 12, 2024
Technology
0
240
JEP 480: Structured Concurrency
2024/09/12 JJUGナイトセミナー Java 23リリース記念イベント
https://jjug.doorkeeper.jp/events/175516
Aya Ebata
September 12, 2024
Tweet
Share
More Decks by Aya Ebata
See All by Aya Ebata
Flutterハンズオン 5
aya_ebata
0
49
Flutterハンズオン 4
aya_ebata
0
85
Flutterハンズオン 3
aya_ebata
0
47
Flutterハンズオン 2
aya_ebata
0
55
Flutterハンズオン 1
aya_ebata
0
85
あたらしい もじれつの かきかた
aya_ebata
0
98
社内勉強会vol.3@ごーふぁー荘
aya_ebata
0
740
社内勉強会vol.2@ごーふぁー荘
aya_ebata
1
750
社内勉強会vol.1@ごーふぁー荘
aya_ebata
0
690
Other Decks in Technology
See All in Technology
Model Mondays S2E02: Model Context Protocol
nitya
0
220
Navigation3でViewModelにデータを渡す方法
mikanichinose
0
220
Javaで作る RAGを活用した Q&Aアプリケーション
recruitengineers
PRO
1
100
MySQL5.6から8.4へ 戦いの記録
kyoshidaxx
1
190
OpenHands🤲にContributeしてみた
kotauchisunsun
1
420
AIのAIによるAIのための出力評価と改善
chocoyama
2
540
CI/CD/IaC 久々に0から環境を作ったらこうなりました
kaz29
1
160
Snowflake Summit 2025 データエンジニアリング関連新機能紹介 / Snowflake Summit 2025 What's New about Data Engineering
tiltmax3
0
310
Agentic Workflowという選択肢を考える
tkikuchi1002
1
490
Liquid Glass革新とSwiftUI/UIKit進化
fumiyasac0921
0
190
Welcome to the LLM Club
koic
0
160
VISITS_AIIoTビジネス共創ラボ登壇資料.pdf
iotcomjpadmin
0
160
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
81
9.1k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
Typedesign – Prime Four
hannesfritz
42
2.7k
The Invisible Side of Design
smashingmag
299
51k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
138
34k
BBQ
matthewcrist
89
9.7k
Navigating Team Friction
lara
187
15k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
20k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Transcript
JEP 480: Structured Concurrency 2024/09/12 JJUGナイトセミナー Java 23リリース記念イベント えばた あや
@aya_122
自己紹介 - 名前: えばた あや - Twitter: @aya_122 - 好き:
ラーメン二郎 / いくら🍣 / ポケモン - お仕事: フリーランス - Go / React / Android - 最近Flutterに入門した🤘
今日話すこと JEP 480: Structured Concurrency (Third Preview) https://openjdk.org/jeps/480
Structured Concurrencyとは - Java 23のJEP 480にてプレビュー機能として提案された - 並行プログラミングを簡素化するために導入
Structured Concurrencyとは - 異なるスレッドで実行される関連するタスクの グループを単一の作業単位として扱い、 エラー処理とキャンセルを合理化する
Structured Concurrencyとは - キャンセルやシャットダウンに起因する一般的なリスクを排除 - スレッドリークやキャンセル遅延など - 並行コードのobservabilityを向上させる - スレッドダンプを取った時、サブタスクのスレッドが何を
しているかが見やすくなる
リリースの歴史 JDK 19 JEP 428: Incubator ↓ JDK 20 JEP 437: Second
Incubator、JEP 429 ↓ JDK 21 JEP 435: Preview ↓ JDK 22 JEP 462: Second Preview ↓ JDK 23 JEP 480: Third Preview(今回の!)
並行処理の利点 - 通常のシングルスレッドでは、サブタスクが順次実行される - サブタスクを同時に実行することで、タスクをより高速に実行できる ようになる - 複数の処理が互いに独立している場合 - 十分なハードウェアリソースがある場合
今までの並行処理の書き方 - ExecutorServiceとFutureを使用することでサブタスクを同時に実行 try (ExecutorService esvc = Executors.newFixedThreadPool(2)) { Future<String>
user = esvc.submit(() -> findUser()); Future<String> order = esvc.submit(() -> fetchOrder()); System.out.println(user.get()); System.out.println(order.get()); }
今までの並行処理の書き方の欠点 - 各サブタスクは独立して成功したり失敗したりする - 失敗すると、スレッドの寿命を理解するのが複雑になる場合がある - あるサブタスクが失敗した場合、別のサブタスクのキャンセルを 自動的に引き起こすことはない -> これがStructured
Concurrencyで改善される -> 次のページで欠点の例を見ていくよ
今までの並行処理の書き方 欠点の例 - findUser()が例外を投げると、user.get()を呼び出すときに例外を スローし、fetchOrder()は自身のスレッドで実行し続けるが、結果は 取得できない try (ExecutorService esvc = Executors.newFixedThreadPool(2))
{ Future<String> user = esvc.submit(() -> findUser()); ⬅ 例外が発生 Future<String> order = esvc.submit(() -> fetchOrder()); ⬅ 実行し続ける System.out.println(user.get()); ⬅ ここで例外がスローされる System.out.println(order.get()); ⬅ すでにエラーで落ちて取得できない }
今までの並行処理の書き方 欠点の例 - findUser()の実行に時間がかかりその間にfetchOrder()が 失敗した場合、findUser()の完了を待った後にorder.get()が例外を スローする try (ExecutorService esvc = Executors.newFixedThreadPool(2))
{ Future<String> user = esvc.submit(() -> findUser()); ⬅ 長い処理 Future<String> order = esvc.submit(() -> fetchOrder()); ⬅ 例外が発生 System.out.println(user.get()); ⬅ findUser()終了後、値が取得できる System.out.println(order.get()); ⬅ 例外がスローされる }
StructuredTaskScopeクラスとは - java.util.concurrentパッケージのStructuredTaskScopeが Structured Concurrency APIの主要なクラス - StructuredTaskScopeを使うと、サブタスクの成功した結果や 例外が集約され、親タスクによって処理される -
サブタスクのライフタイムをレキシカルスコープで限定し、その スコープ内でタスクとサブタスクのすべてのやり取り(フォーク、 結合、キャンセル、エラー処理、結果の合成)が行われる
Structured Concurrencyでの書き方 try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Supplier<String>
user = scope.fork(() -> findUser()); Supplier<String> order = scope.fork(() -> fetchOrder()); scope.join().throwIfFailed(); System.out.println(user.get()); System.out.println(order.get()); }
Structured Concurrencyでの書き方 1. StructuredTaskScope.ShutdownOnFailure()でスコープを作成する - サブタスクのいずれかが失敗した場合、もう一方のサブタスクが キャンセルされる - try-with-resourcesでスコープが閉じられると、サブタスクの 全てのスレッドは終了する
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { // ... }
Structured Concurrencyでの書き方 2. fork()メソッドを使用して、新しいスレッドを作成する - 型はFutureではなくSupplierになる Supplier<String> user = scope.fork(()
-> findUser()); Supplier<String> order = scope.fork(() -> fetchOrder());
Structured Concurrencyでの書き方 3. join()メソッドですべてのサブタスクを1つの ユニットとして結合し、すべてのサブタスクが 成功するか、キャンセルされるまで待つ - throwIfFailed()メソッドは最初に失敗した サブタスクの例外をスローする scope.join().throwIfFailed();
Structured Concurrencyでの書き方 5. 結合後、get()メソッドでその結果を返す System.out.println(user.get()); System.out.println(order.get());
shutdown()メソッド - スコープのオーナー、スコープ内のサブタスク、ネストされた スコープ内のサブサブタスクは、いつでもshutdown()メソッドを 呼び出してタスクを終了できる - shutdown()メソッドの呼び出し後にフォークされた新しいサブタスク はUNAVAILABLE状態になり実行されない
joinUntil()メソッド - joinUntil()メソッドを使うと指定した期限まで待つことができる - サブタスクが終了するか、shutdown()メソッドが呼び出される前に joinUntil()メソッドの期限が切れると、例外がスローされる
シャットダウンポリシー - StructuredTaskScope.ShutdownOnFailure()はサブタスクが失敗 した時にスコープをシャットダウンするポリシー - StructuredTaskScope.ShutdownOnSuccess()はサブタスクが成功 した時にスコープをシャットダウンするポリシー - 継承してオーバーライドするとカスタマイズ可能
ShutdownOnSuccess()を使う場合 - result()メソッドは最初に成功したサブタスクの結果を返す try (var scope = new StructuredTaskScope.ShutdownOnSuccess<String>()) {
scope.fork(() -> findUser()); scope.fork(() -> fetchOrder()); System.out.println(scope.join().result()); }
まとめ - StructuredTaskScopeクラスを使用してスレッドを立てると - 一般的なリスクを排除できる - 一方のサブタスクが成功/失敗をすると、残りのサブタスクを キャンセルできる - サブタスクが成功した時、失敗した時など、処理がわかりやすくなる