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
99
社内勉強会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
Delegating the chores of authenticating users to Keycloak
ahus1
0
130
2年でここまで成長!AWSで育てたAI Slack botの軌跡
iwamot
PRO
4
770
GeminiとNotebookLMによる金融実務の業務革新
abenben
0
240
生成AI時代の開発組織・技術・プロセス 〜 ログラスの挑戦と考察 〜
itohiro73
1
290
低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 / Building a C Compiler for PHPers Who Want to Dive into Low-Level Programming - Expanded
tomzoh
4
3.3k
Understanding_Thread_Tuning_for_Inference_Servers_of_Deep_Models.pdf
lycorptech_jp
PRO
0
140
TechLION vol.41~MySQLユーザ会のほうから来ました / techlion41_mysql
sakaik
0
190
強化されたAmazon Location Serviceによる新機能と開発者体験
dayjournal
3
230
変化する開発、進化する体系時代に適応するソフトウェアエンジニアの知識と考え方(JaSST'25 Kansai)
mizunori
1
230
生成AIで小説を書くためにプロンプトの制約や原則について学ぶ / prompt-engineering-for-ai-fiction
nwiizo
4
2.5k
25分で解説する「最小権限の原則」を実現するための AWS「ポリシー」大全 / 20250625-aws-summit-aws-policy
opelab
9
1.2k
JEDAI Databricks Free Editionもくもく会
taka_aki
1
100
Featured
See All Featured
Git: the NoSQL Database
bkeepers
PRO
430
65k
Unsuck your backbone
ammeep
671
58k
Fireside Chat
paigeccino
37
3.5k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
48
5.4k
The Cult of Friendly URLs
andyhume
79
6.5k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
How to Ace a Technical Interview
jacobian
277
23k
Embracing the Ebb and Flow
colly
86
4.7k
Building Applications with DynamoDB
mza
95
6.5k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
It's Worth the Effort
3n
185
28k
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クラスを使用してスレッドを立てると - 一般的なリスクを排除できる - 一方のサブタスクが成功/失敗をすると、残りのサブタスクを キャンセルできる - サブタスクが成功した時、失敗した時など、処理がわかりやすくなる