0Pricing
Java Academy · Lekcja

StructuredTaskScope

Rozgałęzianie i łączenie podzadań

StructuredTaskScope to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.

Poznaj StructuredTaskScope

StructuredTaskScope to podstawowe API współbieżności strukturalnej. Zakres jest otwierany, podzadania uruchamiane za pomocą fork, następnie wywoływany jest join, aby na nie zaczekać, a potem odczytywane są ich wyniki.

Jest to funkcja w wersji preview, dlatego program należy kompilować i uruchamiać z użyciem --enable-preview.

Podstawowy cykl życia

Każde użycie przebiega według tego samego czterostopniowego schematu:

  • Otworzyć zakres w bloku try-with-resources
  • Wywołać fork dla co najmniej jednego podzadania, z których każde zwraca uchwyt Subtask
  • Wywołać join, aby zaczekać na zakończenie
  • Odczytać wynik każdego podzadania za pomocą get()

fork zwraca uchwyt

fork(Callable) natychmiast uruchamia podzadanie na wirtualnym wątku i zwraca obiekt Subtask. Nie wolno wywoływać jego get() przed zakończeniem działania join().

Kompletny przykład

W tym przykładzie dwa podzadania działają współbieżnie. Oba muszą się zakończyć, zanim odczytamy wyniki. Wykorzystano wbudowaną zasadę 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, a następnie odczyt

Reguła kolejności jest ścisła: fork, następnie join, a potem get. Wywołanie get() na podzadaniu przed zakończeniem join() powoduje zgłoszenie wyjątku IllegalStateException.

To ta reguła zapewnia uporządkowany cykl życia.

Stany podzadań

Po wywołaniu join() każde podzadanie Subtask zgłasza stan za pomocą state():

  • SUCCESS z wynikiem dostępnym przez get()
  • FAILED z wyjątkiem dostępnym przez exception()
  • UNAVAILABLE, jeśli podzadanie nigdy nie zostało ukończone

Wiele podzadań

Można wywołać fork dla dowolnej liczby podzadań; każde otrzyma własny wątek wirtualny. W ten sposób rozdziela się partię niezależnych wywołań na wiele zadań.

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);
        }
    }
}

Zakres zarządza wątkami

Zakres jest obiektem AutoCloseable. Gdy kończy się blok try, metoda close() gwarantuje, że każdy wątek podzadania zakończył działanie. Wycieki są niemożliwe.

Dlatego zawsze należy używać zakresu wewnątrz bloku try-with-resources.

Wbudowane zasady

JDK dostarcza dwie gotowe zasady zamykania:

  • ShutdownOnFailure: anulowanie pozostałych podzadań, jeśli którekolwiek zakończy się niepowodzeniem
  • ShutdownOnSuccess: anulowanie pozostałych podzadań, gdy którekolwiek zakończy się powodzeniem

Można także utworzyć podklasę StructuredTaskScope, aby zaimplementować własną logikę.

join z tego samego wątku

Tylko wątek, który otworzył zakres, może wywoływać w nim fork i join. Podzadania są ograniczone do należącego do nich zakresu, co zapewnia poprawną strukturę drzewa.

Flagi kompilacji i uruchamiania

Ponieważ API jest funkcją w wersji preview, należy kompilować za pomocą:

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

Bez tej flagi pojawi się błąd kompilacji lub uruchamiania.

Szybkie sprawdzenie

Proszę przypomnieć sobie obowiązkową kolejność wywołań.

Podsumowanie

Poznali Państwo API StructuredTaskScope:

  • Otwieranie w try-with-resources, następnie fork, join i get
  • Każde podzadanie działa na własnym wątku wirtualnym
  • Zakres gwarantuje zakończenie wszystkich podzadań przed zamknięciem
  • Wymaga --enable-preview

Następnie: szczegółowe omówienie zasad zamykania po niepowodzeniu i po powodzeniu.

Często zadawane pytania

Czy lekcja „StructuredTaskScope” jest bezpłatna?

Tak — pełny tekst „StructuredTaskScope” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „StructuredTaskScope”?

Rozgałęzianie i łączenie podzadań Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Java Academy?

Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „StructuredTaskScope”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?

Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Model współbieżności strukturalnej
  2. StructuredTaskScope
  3. Zamykanie po błędzie i powodzeniu
  4. Obsługa błędów i anulowanie
← Powrót do Java Academy