0Pricing
Java Academy · Lekcja

Zamykanie po błędzie i powodzeniu

Koordynowanie wyników zadań

Zamykanie po błędzie i powodzeniu to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 3 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.

Dwa typowe wzorce

Większość przypadków rozdzielania pracy współbieżnej przyjmuje jeden z dwóch kształtów:

  • Wszystkie muszą zakończyć się powodzeniem: jeśli którekolwiek podzadanie zakończy się niepowodzeniem, pozostałe są porzucane. Należy użyć ShutdownOnFailure.
  • Wygrywa pierwsze: gdy tylko jedno podzadanie zakończy się powodzeniem, pozostałe są anulowane. Należy użyć ShutdownOnSuccess.

JDK udostępnia obie zasady od razu.

Idea ShutdownOnFailure

ShutdownOnFailure służy do zadań, które wszystkie muszą zakończyć się powodzeniem, takich jak jednoczesne pobranie profilu użytkownika i jego zamówień.

Jeśli jedno z podzadań zgłosi wyjątek, zakres anuluje pozostałe, aby nie marnować pracy.

Przykład ShutdownOnFailure

Po wywołaniu join() wywołuje się throwIfFailed(), które ponownie zgłasza pierwsze niepowodzenie (jeśli wystąpiło), opakowane w ExecutionException.

import java.util.concurrent.StructuredTaskScope;

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

    static String fetch(String what) {
        return what + "-ok";
    }
}

Działanie throwIfFailed

throwIfFailed() sprawdza podzadania. Jeśli wszystkie zakończyły się powodzeniem, nic nie robi. Jeśli którekolwiek zakończyło się niepowodzeniem, zgłasza wyjątek, opakowując pierwotny wyjątek.

Można także przekazać funkcję mapującą przyczynę na własny typ wyjątku.

Idea ShutdownOnSuccess

ShutdownOnSuccess służy do redundancji lub wyścigów: wysyła zapytanie do kilku serwerów lustrzanych i przyjmuje odpowiedź, która nadejdzie jako pierwsza.

W chwili, gdy jedno z podzadań zakończy się powodzeniem, zakres anuluje pozostałe i zapisuje zwycięski wynik.

Przykład ShutdownOnSuccess

Zwycięską wartość pobiera się za pomocą result(). Metoda zgłasza wyjątek, jeśli żadne podzadanie nie zakończyło się powodzeniem.

import java.util.concurrent.StructuredTaskScope;

public class Main {
    public static void main(String[] args) throws Exception {
        try (var scope = new StructuredTaskScope.ShutdownOnSuccess<String>()) {
            scope.fork(() -> queryMirror("eu"));
            scope.fork(() -> queryMirror("us"));
            scope.join();
            System.out.println("Fastest answer: " + scope.result());
        }
    }

    static String queryMirror(String region) {
        return region + "-data";
    }
}

result a get

Proszę zwrócić uwagę na różnicę:

  • ShutdownOnFailure: odczytywanie każdego podzadania za pomocą jego własnego get()
  • ShutdownOnSuccess: odczytywanie jednego zwycięskiego podzadania za pomocą result() zakresu

Anulowanie odbywa się kooperacyjnie

Gdy zakres zostaje zamknięty, przerywa pozostałe wątki podzadań. Zadania poprawnie reagujące na przerwania sprawdzają stan przerwania i szybko się zatrzymują.

Wywołania blokujące w standardowej bibliotece na ogół automatycznie reagują na przerwanie.

join z limitem czasu

Obie zasady obsługują termin. Wywołanie joinUntil(Instant) czeka tylko do określonego momentu, a następnie zgłasza TimeoutException i zamyka zakres.

Wybór zasady

Proszę zadać sobie jedno pytanie: czy potrzebne są wszystkie wyniki, czy tylko pierwszy?

  • Wszystkie wyniki, szybkie zakończenie po błędzie: ShutdownOnFailure
  • Dowolny jeden wynik, wygrywa najszybszy: ShutdownOnSuccess

W pozostałych przypadkach należy utworzyć podklasę StructuredTaskScope.

Własne zasady

Można rozszerzyć StructuredTaskScope i przesłonić metodę handleComplete(Subtask), aby zaimplementować niestandardowe reguły, takie jak zebranie pierwszych N wyników zakończonych powodzeniem lub zamknięcie zakresu po przekroczeniu limitu niepowodzeń.

Szybkie sprawdzenie

Proszę dopasować scenariusz do zasady.

Podsumowanie

Poznali Państwo dwie wbudowane zasady zamykania:

  • ShutdownOnFailure + throwIfFailed + osobne wywołanie get dla każdego podzadania, gdy wszystkie muszą zakończyć się powodzeniem
  • ShutdownOnSuccess + result, gdy wygrywa pierwsze podzadanie
  • Zamykanie zakresu kooperacyjnie przerywa pozostałe podzadania
  • joinUntil dodaje terminy, a tworzenie podklas umożliwia dodawanie własnych reguł

Następnie: szczegółowe omówienie obsługi błędów i anulowania.

Często zadawane pytania

Czy lekcja „Zamykanie po błędzie i powodzeniu” jest bezpłatna?

Tak — pełny tekst „Zamykanie po błędzie i powodzeniu” 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 „Zamykanie po błędzie i powodzeniu”?

Koordynowanie wyników zadań Ć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 3 z 4.

Ile czasu zajmuje lekcja „Zamykanie po błędzie i powodzeniu”?

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