Agradeceríamos tu ayuda para difundir nuestros ensayos con relación a las ciencias informáticas.
Solución:
¿Cuál es la diferencia entre las siguientes formas de manejar InterruptedException? ¿Cuál es la mejor manera de hacerlo?
Probablemente hayas venido a hacer esta pregunta porque has llamado a un método que arroja InterruptedException
.
Primero que nada, deberías ver throws InterruptedException
por lo que es: una parte de la firma del método y un posible resultado de llamar al método que está llamando. Empiece por aceptar el hecho de que un InterruptedException
es un resultado perfectamente válido de la llamada al método.
Ahora, si el método al que está llamando arroja tal excepción, ¿qué debería tu método hacer? Puede averiguar la respuesta pensando en lo siguiente:
¿Tiene sentido para el método? usted están implementando para lanzar un InterruptedException
? Dicho de otra manera, es un InterruptedException
un resultado sensato al llamar tu ¿método?
-
Si sí, luego
throws InterruptedException
debería ser parte de tu firma del método, y debe dejar que la excepción se propague (es decir, no la detecte en absoluto).Ejemplo: Su método espera un valor de la red para finalizar el cálculo y devolver un resultado. Si la llamada de red de bloqueo arroja un
InterruptedException
su método no puede finalizar el cálculo de forma normal. Dejas que elInterruptedException
propagar.int computeSum(Server server) throws InterruptedException // Any InterruptedException thrown below is propagated int a = server.getValueA(); int b = server.getValueB(); return a + b;
-
Si no, entonces no debes declarar tu método con
throws InterruptedException
y debería (¡debe!) capturar la excepción. Ahora es importante tener en cuenta dos cosas en esta situación:-
Alguien interrumpió tu hilo. Es probable que alguien esté ansioso por cancelar la operación, terminar el programa con gracia o lo que sea. Debe ser cortés con esa persona y regresar de su método sin más preámbulos.
-
Aunque tu El método puede llegar a producir un valor de retorno sensible en caso de un
InterruptedException
el hecho de que se haya interrumpido el hilo puede ser importante. En particular, el código que llama a su método puede estar interesado en saber si ocurrió una interrupción durante la ejecución de su método. Por lo tanto, debe registrar el hecho de que se produjo una interrupción configurando el indicador de interrupción:Thread.currentThread().interrupt()
Ejemplo: El usuario ha solicitado imprimir una suma de dos valores. Imprimiendo “
Failed to compute sum
“es aceptable si la suma no se puede calcular (y mucho mejor que dejar que el programa se bloquee con un seguimiento de pila debido a unaInterruptedException
). En otras palabras, lo hace no tiene sentido declarar este método conthrows InterruptedException
.void printSum(Server server) try int sum = computeSum(server); System.out.println("Sum: " + sum); catch (InterruptedException e) Thread.currentThread().interrupt(); // set interrupt flag System.out.println("Failed to compute sum");
-
A estas alturas debería estar claro que simplemente haciendo throw new RuntimeException(e)
es una mala idea. No es muy educado con la persona que llama. Podría inventar una nueva excepción de tiempo de ejecución, pero la causa raíz (alguien quiere que el hilo detenga la ejecución) podría perderse.
Otros ejemplos:
Implementar
Runnable
: Como habrás descubierto, la firma deRunnable.run
no permite volver a lanzarInterruptedExceptions
. Bien, usted inscrito en la implementaciónRunnable
, Lo que significa que usted inscrito para hacer frente a posiblesInterruptedExceptions
. Elija una interfaz diferente, comoCallable
, o siga el segundo enfoque anterior.
Vocación
Thread.sleep
: Está intentando leer un archivo y la especificación dice que debe intentarlo 10 veces con 1 segundo entre ellas. LlamaThread.sleep(1000)
. Entonces, debes lidiar conInterruptedException
. Para un método comotryToReadFile
tiene mucho sentido decir “Si me interrumpen, no puedo completar mi acción de intentar leer el archivo”. En otras palabras, tiene mucho sentido que el método arrojeInterruptedExceptions
.String tryToReadFile(File f) throws InterruptedException for (int i = 0; i < 10; i++) if (f.exists()) return readFile(f); Thread.sleep(1000); return null;
Esta publicación ha sido reescrita como un artículo aquí.
Da la casualidad de que estaba leyendo sobre esto esta mañana camino al trabajo en Java Concurrency In Practice por Brian Goetz. Básicamente dice que debes hacer una de tres cosas
-
Propagar el
InterruptedException
- Declare su método para lanzar el marcadoInterruptedException
para que su interlocutor tenga que ocuparse de ello. -
Restaurar la interrupción - A veces no puedes lanzar
InterruptedException
. En estos casos deberías coger elInterruptedException
y restaurar el estado de interrupción llamando alinterrupt()
método en elcurrentThread
para que el código más arriba en la pila de llamadas pueda ver que se emitió una interrupción y regresar rápidamente del método. Nota: esto solo es aplicable cuando su método tiene semántica de "prueba" o "mejor esfuerzo", es decir, no pasaría nada crítico si el método no logra su objetivo. Por ejemplo,log()
osendMetric()
puede ser tal método, oboolean tryTransferMoney()
, pero novoid transferMoney()
. Consulte aquí para obtener más detalles. - Ignore la interrupción dentro del método, pero restaure el estado al salir - por ejemplo, a través de Guayaba
Uninterruptibles
.Uninterruptibles
asumir el código repetitivo como en el ejemplo de Tarea no cancelable en JCIP § 7.1.3.
¿Que estás tratando de hacer?
los InterruptedException
se lanza cuando un hilo está esperando o durmiendo y otro hilo lo interrumpe usando el interrupt
método en clase Thread
. Entonces, si detecta esta excepción, significa que el hilo se ha interrumpido. Por lo general, no tiene sentido llamar Thread.currentThread().interrupt();
de nuevo, a menos que desee comprobar el estado "interrumpido" del hilo desde otro lugar.
En cuanto a tu otra opción de lanzar un RuntimeException
, no parece una decisión muy inteligente (¿quién se dará cuenta de esto? ¿Cómo se manejará?), pero es difícil decir más sin información adicional.
Puedes añadir valor a nuestra información dando tu veteranía en las observaciones.