0Pricing
Java Academy · レッスン

StructuredTaskScope

サブタスクをフォークして結合します。

「StructuredTaskScope」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

StructuredTaskScopeを見てみる

StructuredTaskScopeは、構造化された並行性の中核APIです。スコープを開き、サブタスクをforkし、joinして完了を待ち、その後で結果を読み取ります。

これはプレビュー機能であるため、--enable-previewを付けてコンパイルと実行を行います。

基本的なライフサイクル

すべての使用方法は、次の4つの手順で構成されます。

  • try-with-resourcesブロックでスコープを開きます
  • 1つ以上のサブタスクをforkします。それぞれからSubtaskハンドルが返されます
  • joinして完了を待ちます
  • get()を使って各サブタスクの結果を読み取ります

Forkはハンドルを返す

fork(Callable)は仮想スレッド上でサブタスクを直ちに開始し、Subtaskを返します。join()が返るまでは、そのget()を呼び出してはいけません。

完全な例

ここでは、2つのサブタスクが同時に実行されます。結果を読み取る前に、両方が完了していなければなりません。組み込みのポリシーであるShutdownOnFailureを使用しています。

import java.util.concurrent.StructuredTaskScope;

public class Main {
    public static void main(String[] args) throws Exception {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            var name = scope.fork(() -> "Grace");
            var count = scope.fork(() -> 3);
            scope.join();
            scope.throwIfFailed();
            System.out.println(name.get() + " placed " + count.get() + " orders");
        }
    }
}

joinしてから読み取る

呼び出し順序には厳密なルールがあります。fork、次にjoin、最後にgetです。join()が完了する前にサブタスクのget()を呼び出すと、IllegalStateExceptionがスローされます。

このルールによって、存続期間の構造が保たれます。

サブタスクの状態

join()の後、各Subtaskはstate()で状態を報告します。

  • SUCCESSの場合は、get()で結果を取得できます
  • FAILEDの場合は、exception()で例外を取得できます
  • 完了していない場合はUNAVAILABLEになります

多数のサブタスク

サブタスクは好きなだけforkできます。それぞれに専用の仮想スレッドが割り当てられます。これにより、独立した呼び出しのバッチに処理を分散できます。

import java.util.*;
import java.util.concurrent.StructuredTaskScope;

public class Main {
    public static void main(String[] args) throws Exception {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            List<StructuredTaskScope.Subtask<Integer>> tasks = new ArrayList<>();
            for (int i = 1; i <= 5; i++) {
                final int n = i;
                tasks.add(scope.fork(() -> n * n));
            }
            scope.join();
            scope.throwIfFailed();
            int total = tasks.stream().mapToInt(StructuredTaskScope.Subtask::get).sum();
            System.out.println("Sum of squares 1..5 = " + total);
        }
    }
}

スコープがスレッドを管理する

スコープはAutoCloseableです。tryブロックが終了すると、close()によってすべてのサブタスクのスレッドが終了したことが保証されます。リソースリークは発生しません。

そのため、必ずtry-with-resourcesの中で使用します。

組み込みポリシー

JDKには、すぐに使える2つのシャットダウンポリシーが用意されています。

  • ShutdownOnFailure:いずれかのサブタスクが失敗したら、残りをキャンセルします
  • ShutdownOnSuccess:1つが成功したら、残りをキャンセルします

また、StructuredTaskScopeをサブクラス化して、独自のロジックを実装することもできます。

同じスレッドでjoinする

スコープを開いたスレッドだけが、そのスコープにforkし、joinを呼び出せます。サブタスクは、それを所有するスコープ内に限定されるため、ツリー構造が正しく保たれます。

コンパイルと実行のオプション

このAPIはプレビューであるため、次のようにビルドします。

  • javac --release 21 --enable-preview Main.java
  • java --enable-preview Main

このオプションを付けないと、コンパイルエラーまたは実行時エラーが発生します。

理解度チェック

必須の呼び出し順序を思い出しましょう。

まとめ

StructuredTaskScope APIについて学びました。

  • try-with-resourcesで開き、fork、join、getの順に呼び出します
  • 各サブタスクは専用の仮想スレッド上で実行されます
  • スコープを閉じる前に、すべてのサブタスクが終了することが保証されます
  • --enable-previewが必要です

次は、シャットダウン時の失敗処理と成功処理のポリシーについて詳しく学びます。

よくある質問

「StructuredTaskScope」レッスンは無料ですか?

はい。「StructuredTaskScope」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「StructuredTaskScope」で何を学びますか?

サブタスクをフォークして結合します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「StructuredTaskScope」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 構造化並行性モデル
  2. StructuredTaskScope
  3. 失敗時と成功時のシャットダウン
  4. エラー処理とキャンセル
← Java Academyに戻る