and deliver Java VM features and APIs built on top of them for the purpose of supporting easy-to-use, high-throughput lightweight concurrency and new programming models on the Java platform. “ Main - Main - OpenJDK Wiki Javaプラットフォーム上で使いやすく、高スループットの軽量な並行処理と新しいプログラミングモデルをサポートするための、 Java VMの機能とAPIを提供することを目指したプロジェクト
all return to the same place, namely the task's code block.” (タスクが並行サブタスクに分割されたら、それらはすべて同じ場所、つまりタスクの コードブロックに戻る) そのために 1. コードのブロックを流れる実行の入口と出口を明確に定義されなければならない 2. コードの構文上の入れ子構造を反映するように、操作のライフタイムが厳密に入れ子構造になっている必要 がある
= new StructuredTaskScope.ShutdownOnFailure()) { Supplier<String> user = scope.fork(() -> findUser()); Supplier<Integer> order = scope.fork(() -> fetchOrder()); // 両サブタスクを待ち受け、エラー発生時には例外を投げる scope.join().throwIfFailed(); // 両サブタスクが成功したら、両者の結果をまとめる return new Response(user.get(), order.get()); } } ① スレッドのライフタイムはtry-with-resources内に限定 ② findUser()サブタスクまたはfetchOrder()サブタスクのいずれかが失敗した場合、それがまだ完了していな ければ、もう一方のサブタスクはキャンセル (ShutdownOnFailureのシャットダウン・ポリシーによる) ③ join()の呼び出しの前または呼び出し中にhandle()を実行しているスレッドが割り込まれた場合、そのスレッド がスコープを抜けると、両方のサブタスクが自動的にキャンセル ④ thread dumpはタスク階層を明確に表す 【例】findUser()とfetchOrder()を実行しているスレッドはスコープの子として表示 ① ②
= new ThreadLocal<>(); void serve(Request request, Response response) { var level = (request.isAuthorized() ? ADMIN : GUEST); var principal = new Principal(level); PRINCIPAL.set(principal); Application.handle(request, response); } } class DBAccess { DBConnection open() { var principal = Server.PRINCIPAL.get(); if (!principal.canOpen()) throw new InvalidPrincipalException(); return newConnection(...); } }