Futuro <T> .get () atrapado cuando el ejecutable lanza una excepción - mientras se ejecuta en el servicio ejecutor separada?

Steven Luu:

Un repro aquí:

import java.util.concurrent.*;

public class Main {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("Hello!");

        ExecutorService exec = Executors.newSingleThreadExecutor();

        Future<Integer> f = exec.submit(() -> x());

        f.get();

        System.out.println("f.get() returned");

        exec.shutdownNow();

        System.out.println("Good bye!");
    }

    private static Integer x() {
        throw new RuntimeException("An unfortunate event");
    }
}

La salida sólo muestra "Hola!" y la StackTrace excepción, luego se cuelga el programa para siempre.

Los cambios siguientes tipo de trabajo alrededor del problema, pero ninguna idea de por qué se bloquea la ejecución en el código anterior?

El uso de la piscina hilo común no cuelgue:

Future<Integer> f = ForkJoinPool.commonPool().submit(() -> x());

Envolver alrededor de la llamada try / catch permite la salida de la aplicación normalmente:

Future<Integer> f = exec.submit(() -> x());

try {
    f.get();
} catch (Exception ex) {
    ex.printStackTrace();
}
Andrew Tobilko:

Siempre es difícil encontrar un buen ejemplo de try-finallyy su uso apropiado. Creo que es el caso.

try {
    f.get();
    System.out.println("f.get() returned");
} finally {
    exec.shutdownNow();
}

La excepción lanzada desde f.get();no fue manejado, el hilo principal ha fallado. Sin embargo, la aplicación todavía contiene hilos no demonio manejable por el ExecutorServicea la que no tiene acceso directo.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=206837&siteId=1
Recomendado
Clasificación