2009-06-21 6 views
30

Estoy usando java.util.concurrent.Semaphore en un proyecto de hobby. Se usa en una clase de grupo de conexión que estoy escribiendo. Puedo usarlo con poco ruido, excepto por este método:¿Debo preocuparme por InterruptedExceptions si no interrumpo nada por mi cuenta?

public void acquire(int permits) throws InterruptedException 

la que me obliga a manejar el InterruptedException. Ahora, no estoy seguro de qué significa "interrumpir" un hilo ni siquiera y nunca lo hago (bueno, no explícitamente) en mi código. ¿Esto significa que puedo ignorar la excepción? ¿Cómo debo manejarlo?

Respuesta

1

Los hilos pueden ser interrumpidos llamando a Thread.interrupt(). Se usa para señalar con gracia un hilo que debería hacer otra cosa. Usualmente causa que las operaciones de bloqueo (por ejemplo, Thread.sleep()) regresen antes y lanzan la InterruptedException. Si el hilo se interrumpe, se establece un indicador en él. Esta bandera se puede consultar a través de la llamada Thread.isInterrupted().

Si no utiliza la interrupción de hilo y aún obtiene esta excepción, puede simplemente salir de su hilo (y registrar la excepción preferiblemente).

En general, depende de lo que haga su aplicación de subprocesos múltiples.

0

Debe salir del método run() luego de realizar la limpieza requerida por su Thread.
HTH

6

Nope. InterruptedException solo se genera si usted mismo interrumpe el hilo. Si usted mismo no usa Thread.interrupt(), entonces lo volvería a lanzar como una especie de "excepción inesperada" o lo registraría como un error y seguiría adelante. Por ejemplo, en mi código cuando me veo obligado a coger InterruptedException y nunca llamo interrupt() mí mismo, hago el equivalente de

catch (InterruptedException exception) { 
    throw new RuntimeException("Unexpected interrupt", exception); 
} 

Eso es si es inesperado. Hay muchos lugares donde deliberadamente interrumpo mis hilos y en esos casos manejo los InterruptedException s de una manera bien definida. Por lo general, eso es saliendo del bucle en el que estoy, limpiando y luego deteniendo el hilo.

1

Si usted no sabe cómo manejar la situación en un método que sugiero se declara en el método con tiros InterruptedException (y que la persona que llama, etc)

Si algo que nunca esperar que ocurra lo haría atraparlo y envuélvalo en un AssertionError.

27

Sí, usted necesita preocúpese por InterruptedException, del mismo modo que debe preocuparse por cualquier otra excepción comprobada que debe arrojar o manejar.

La mayoría de las veces un InterruptedException señala una solicitud de detención, muy probablemente debido al hecho de que el hilo que estaba ejecutando el código era interrupted.

En su situación particular de un grupo de conexión esperando para obtener una conexión, diría que este es un problema de cancelación y debe cancelar la adquisición, la limpieza y restaurar el indicador interrumpido (ver a continuación).


A modo de ejemplo, si está utilizando algún tipo de Runnable/Callable se ejecuta dentro de un Executor entonces usted necesita para manejar la InterruptedException correctamente:

executor.execute(new Runnable() { 

    public void run() { 
     while (true) { 
       try { 
       Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        continue; //blah 
       } 
       pingRemoteServer(); 
     } 
    } 
}); 

Esto significaría que su tarea no obedece el mecanismo de interrupción utilizado por el ejecutor y no permite una cancelación/apagado adecuado.

En cambio, el lenguaje adecuado es restaurar el estado interrumpe y luego se detiene la ejecución:

executor.execute(new Runnable() { 

    public void run() { 
     while (true) { 
       try { 
       Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        Thread.currentThread().interrupt(); // restore interrupted status 
        break; 
       } 
       pingRemoteServer(); 
     } 
    } 
}); 

Recursos útiles:

+3

Absolutamente. Para obtener más información, consulte el boletín de especialistas de Java http://www.javaspecialists.co.za/archive/Issue056.html –

+1

¿No debería ser Thread.currentThread(). Interrupt() en lugar de Thread.interrupted()? Según los javadocs, Thread.interrupted() borrará el indicador interrumpido, no lo configurará. –

+0

@Joe: tienes razón, he corregido el ejemplo. Gracias. –

Cuestiones relacionadas