Gestión de errores y cancelación
Propague los fallos correctamente
Gestión de errores y cancelación es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.
Fallos en un árbol de tareas
Cuando las subtareas se ejecutan de forma concurrente, pueden producirse errores en cualquier rama. La concurrencia estructurada ofrece una forma disciplinada de propagar esos fallos al elemento principal.
Esta lección aborda las excepciones, la cancelación, la interrupción y los tiempos de espera.
Dónde aparecen las excepciones
Una subtarea que lanza una excepción no bloquea inmediatamente el programa. La excepción se captura en la referencia Subtask. El lugar donde aparece depende de la política:
ShutdownOnFailure: enthrowIfFailed()ShutdownOnSuccess: enresult(), si ninguna subtarea tuvo éxito
Propagación mediante throwIfFailed
Aquí falla una subtarea. throwIfFailed() vuelve a lanzarla encapsulada en una ExecutionException, que capturamos en main.
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws InterruptedException {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
scope.fork(() -> "ok");
scope.fork(() -> { throw new RuntimeException("boom"); });
scope.join();
scope.throwIfFailed();
System.out.println("never reached");
} catch (ExecutionException e) {
System.out.println("Caught cause: " + e.getCause().getMessage());
}
}
}Conversión a una excepción personalizada
throwIfFailed acepta una función para encapsular la causa en su propio tipo de excepción, lo que mantiene limpia su API.
import java.util.concurrent.StructuredTaskScope;
class DataAccessException extends Exception {
DataAccessException(Throwable cause) { super(cause); }
}
public class Main {
public static void main(String[] args) throws Exception {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
scope.fork(() -> { throw new RuntimeException("db down"); });
scope.join();
scope.throwIfFailed(DataAccessException::new);
} catch (DataAccessException e) {
System.out.println("Wrapped: " + e.getCause().getMessage());
}
}
}Cancelación automática
Cuando falla una subtarea con ShutdownOnFailure, el ámbito cancela las subtareas hermanas interrumpiendo sus hilos. No tiene que escribir código de cancelación.
Esto evita el trabajo desperdiciado y las tareas abandonadas.
La interrupción es el mecanismo
La cancelación funciona al interrumpir el hilo virtual de la subtarea. El código cooperativo debe:
- Permitir que las llamadas bloqueantes lancen
InterruptedException - Comprobar periódicamente
Thread.currentThread().isInterrupted()en los bucles largos
Responder a la interrupción
Esta tarea comprueba la marca de interrupción en un bucle para poder detenerse antes cuando el ámbito se cierra.
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t = Thread.ofVirtual().start(() -> {
long count = 0;
while (!Thread.currentThread().isInterrupted()) {
count++;
if (count == 1_000_000) break;
}
System.out.println("Stopped after " + count + " iterations");
});
t.join();
}
}Límites de tiempo con joinUntil
Para limitar el tiempo total, utilice joinUntil(Instant). Si llega el límite antes de que finalicen todas las subtareas, lanza una TimeoutException y el ámbito cierra las restantes.
Estructura de un ejemplo con tiempo de espera
Una distribución del trabajo protegida por un tiempo de espera suele tener este aspecto. El límite se aplica al grupo completo, no a cada subtarea por separado.
import java.time.*;
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws InterruptedException {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
scope.fork(() -> "fast");
scope.joinUntil(Instant.now().plus(Duration.ofSeconds(2)));
scope.throwIfFailed();
System.out.println("Completed within deadline");
} catch (TimeoutException e) {
System.out.println("Deadline exceeded");
} catch (ExecutionException e) {
System.out.println("A subtask failed");
}
}
}Vuelva a comprobar siempre después de join
La disciplina es la siguiente: después de join() o joinUntil, llame siempre a throwIfFailed() o lea result() antes de confiar en cualquier valor de una subtarea. Omitir este paso puede ocultar fallos.
Cierre limpio garantizado
Independientemente de cómo termine un ámbito, de forma normal, por un fallo o por un tiempo de espera, el cierre del bloque try-with-resources garantiza que todos los hilos de las subtareas hayan terminado. No hay fugas ni tareas huérfanas.
Comprobación rápida
Recuerde cómo se detienen las subtareas hermanas.
Resumen
Ha aprendido a gestionar errores y cancelaciones:
- Las excepciones aparecen en
throwIfFailed()oresult() - Convierta las causas en excepciones personalizadas mediante
throwIfFailed(mapper) - La cancelación funciona mediante la interrupción de los hilos; escriba tareas cooperativas
joinUntilimpone un límite de tiempo al grupo- El cierre del ámbito siempre limpia los recursos
Con esto finaliza el curso de concurrencia estructurada.
Preguntas frecuentes
¿La lección «Gestión de errores y cancelación» es gratis?
Sí — el texto completo de «Gestión de errores y cancelación» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Gestión de errores y cancelación»?
Propague los fallos correctamente Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Java Academy?
No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Gestión de errores y cancelación»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Java Academy?
Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- El modelo de concurrencia estructurada
- StructuredTaskScope
- Cierre por fallo y por éxito
- Gestión de errores y cancelación