Saltar al contenido

Manejo de InterruptedException en Java

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 , 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 el InterruptedException 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:

    1. 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.

    2. 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 una InterruptedException). En otras palabras, lo hace no tiene sentido declarar este método con throws 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 de Runnable.run no permite volver a lanzar InterruptedExceptions. Bien, usted inscrito en la implementación Runnable, Lo que significa que usted inscrito para hacer frente a posibles InterruptedExceptions. Elija una interfaz diferente, como Callable, 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. Llama Thread.sleep(1000). Entonces, debes lidiar con InterruptedException. Para un método como tryToReadFile 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 arroje InterruptedExceptions.

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

  1. Propagar el InterruptedException - Declare su método para lanzar el marcado InterruptedException para que su interlocutor tenga que ocuparse de ello.

  2. Restaurar la interrupción - A veces no puedes lanzar InterruptedException. En estos casos deberías coger el InterruptedException y restaurar el estado de interrupción llamando al interrupt() método en el currentThread 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() o sendMetric() puede ser tal método, o boolean tryTransferMoney(), pero no void transferMoney(). Consulte aquí para obtener más detalles.

  3. 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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *