Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


¿Debo hacer `Thread.currentThread (). Interrupt ()` before `throw new InterruptedIOException ()`?

Implemento MyInputStream.read() y MyInputStream.read() que una MyInputStream.read() InterruptedException puede ocurrir dentro de esta función. Después de algunas búsquedas he encontrado que es común para capturar la InterruptedException y volver a lanzar un InterruptedIOException , algo así como:

  try { ... } catch (InterruptedException e) { //Thread.currentThread().interrupt(); // <=== ??? throw new InterruptedIOException(); } 

Pero sólo alrededor del 50% de muestras de código hace Thread.currentThread().interrupt() . Bueno, está de acuerdo en que lo peor que puedes hacer con InterruptedException es tragarlo , pero ¿ debería reinterrupcionar el hilo actual antes de lanzar una excepción diferente?

PRO: una sola solicitud de interrupción puede tener múltiples "destinatarios".

CONTRA: algunas funciones como el registro pueden no estar funcionando antes de que se borre el estado de interrupción, lo que puede causar errores sutiles.

CONTRA: recibimos dos notificaciones sobre la petición de interrupción: el estado interrumpido del hilo y la excepción. Inicialmente, sólo hay una notificación: el estado interrumpido del subproceso es verdadero o se InterruptedException una excepción InterruptedException , pero no ambas.

PRO: nadie prueba realmente el código contra las excepciones de i / o que se pueden lanzar, y el InterruptedIOException es diferente de otras excepciones de i / o; Una cláusula catch(IOException) puede tragar el estado interrumpido.

PS Parece que lo que hago, el problema de que InterruptedIOException es un tipo muy especial de IOException requiere un controlador especial no se resolverá.

PPS (EDIT) No puedo permitir que la throws IOException InterruptedException original se propague porque InputStream.read() no puede lanzar InterruptedException ( throws IOException y no arroja nada más). Y no puedo predecir el contexto en el que se MyInputStream.read() : una instancia de MyInputStream se puede pasar a cualquier función de biblioteca de Java o de terceros que tome un argumento InputStream .

En cuanto al viejo error , parece que estaba cerrado, no fijado; Y la idea misma del estado interrumpido es que el código se comportaría de manera diferente.

3 Solutions collect form web for “¿Debo hacer `Thread.currentThread (). Interrupt ()` before `throw new InterruptedIOException ()`?”

… ¿Debo reinterrupcionar el hilo actual antes de lanzar una excepción diferente?

Si algo upstack va a examinar la bandera de interrupción, entonces sí. De lo contrario, no importa.

CONTRA: algunas funciones como el registro pueden no estar funcionando antes de que se borre el estado de interrupción, lo que puede causar errores sutiles.

Según mi lectura del análisis, el error al que se vinculó sólo se aplica a Java 6 y anteriores, y sólo para la plataforma Solaris. Probablemente puede descontarlo ahora. (A menos que tenga un cliente con bolsillos deeeep, no debería estar haciendo una aplicación significativa para Java 6 o versiones anteriores.)

CONTRA: recibimos dos notificaciones sobre la petición de interrupción: el estado interrumpido del hilo y la excepción.

Son tipos cualitativamente diferentes de notificación …

PS Parece que lo que hago, el problema de que InterruptedIOException es un tipo muy especial de IOException que requiere un controlador especial no se resolverá.

De hecho, una mejor estrategia podría ser establecer el indicador interrumpido en la captura para InterruptedIOException … o simplemente permitir que la excepción Interrupted original se propague.

Debido al siguiente razonamiento:

  1. InterruptedException NO DEBE ser tragado,

  2. Cualquier IOException (y, en particular, InterruptedIOException ) PUEDE ser tragado, es decir, consumido por código de terceros

  3. IOException pretende informar sobre los eventos que ocurren con i / o, no sobre cambios en el estado del hilo

  4. Algún código que no podemos controlar puede establecer o borrar el estado interrumpido del hilo antes de lanzar o volver a lanzar InterruptedIOException

Decidí que:

  1. El subproceso actual DEBE ser reinterrupted antes de lanzar un InterruptedIOException .
  2. El manejo de código InterruptedIOException NO DEBE asumir ningún estado particular del estado interrumpido del hilo
  3. Este comportamiento DEBE ser documentado:

     @throws InterruptedIOException if the current thread is interrupted (the thread interrupted status is true when InterruptedIOException is thrown) @throws IOException if this stream is closed or another IOException occurs. Note that due to possible interference from 3rd-party code, handlers of InterruptedIOException should not assume any particular state of the thread interrupted status when they are invoked. 

Sugiero lanzar una ClosedByInterruptException . Aunque pertenece a la biblioteca NIO, tiene una API mejor definida que la antigua InterruptedIOException , por lo que es más fácil de manejar. Por ejemplo:

 try { ... } catch (InterruptedException e) { close(); // obeying API of ClosedByInterruptException Thread.currentThread().interrupt(); // again, obeying API throw new ClosedByInterruptException(); } 

Véase también Thread # interrupt () . Si en su lugar desea volver a lanzar la excepción original, puede utilizar:

 try { ... } catch (InterruptedException e) { throw e; } 

Así que mantener la pila de seguimiento. El estado de interrupción se deja en este caso, como sugiere la API para InterruptedException .

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.