2012-10-09 12 views
7

¿Cuál es la forma correcta de manejar Thread.interrupted() en un Callable? Supongo que el invocable debería lanzar una InterruptedException; por ejemplo:Manera correcta de manejar Thread.interrupted() en un Callable?

public class MyCallable implements Callable<Object> { 
    public Object call() { 
     Object result = null; 

     // Simulate long-running operation that calculates result 
     while (true) { 
      ... 
      if (Thread.interrupted()) { 
       throw new InterruptedException(); 
      } 
     } 

     result = ... // something produced by the long-running operation  

     return result; 
    } 
} 

¿Es correcto o hay una forma más adecuada de manejarlo? Gracias.

+3

The One True Source para explicar 'InterruptedException' es [aquí] (http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html). –

+0

Lo leí antes, pero no menciona Incullable. Muy buen artículo, sin embargo. –

Respuesta

6

Editar:

Después de algunas idas y vueltas, parece que usted quiere ser capaz de interrumpir sus rutinas de IO. Esto parece un buen trabajo para algunas de las clases de NIO InterrutibleChannel. Por ejemplo, leer de la siguiente BufferedReader es interrumpible y lanzará InterruptedIOException. Consulte aquí para more examples of the NIO code.

BufferedReader in = new BufferedReader(new InputStreamReader(
    Channels.newInputStream((new FileInputStream(
     new File(...))).getChannel()))); 

A continuación, puede llamar future.cancel() que interrumpirá el hilo y hacer que el IO para lanzar una InterruptedIOException. Si eso sucede, podría no atrapar el IOException y dejarlo salir por el método call().


Si desea pasar de nuevo a la Future que el método call() se interrumpió entonces pienso tirar InterruptedException está muy bien. Otra opción sería simplemente return null; u otro objeto marcador de su método call(). Eso es lo que hago normalmente si se interrumpe un hilo.

Una cosa a tener en cuenta es que si call() tiros InterruptedException, cuando se hace una future.get() va a lanzar una ExecutionException y la causa de dicha excepción va a ser un InterruptedException. No se deje confundir que future.get() también arroje un InterruptedException sí el get(long timeout, TimeUnit unit) agota el tiempo.

try { 
    result = future.get(); 
} catch (ExecutionException e) { 
    if (e.getCause() instanceof InterruptedException) { 
     // call() method was interrupted 
    } 
} catch (InterruptedException e) { 
    // get was interrupted 
} 

Si, sin embargo, future.cancel(true) se llamaba entonces el future.get() arrojará un CancellationException lugar.

+0

Proporcionaré un poco más de contexto. Mi código no usa realmente un ciclo while (verdadero) - está leyendo desde un InputStream personalizado que verifica el valor de Thread.interrupted() en read (byte). El método read() arroja InterruptedException para garantizar que el código de llamada (que lee de la transmisión) cierra correctamente la transmisión. –

+0

Resulta que esto no funcionará, ya que read() solo puede lanzar IOException. Parece que lo que quiero podría ser InterruptedIOException. –

+0

Sure @Greg. Otra idea es usar un 'InterruptibleChannel' que sea compatible con NIO. – Gray

1

Depende de cómo quiera que el hilo espere en get(). Si no lo hace quieren el hilo de espera para tener una excepción lanzada entonces usted no desea throw new InterruptedException

Imagínese

try{ 
    future.get(); 
}catch(ExecutionException ex){ 

}catch(InterruptedException em){ 

} 

Si se produce ninguna excepción qué se puede esperar que sea? En su caso, es un ExecutionException. Si no desea un ExecutionException, no debe volver a lanzar la excepción InterruptedException.

+0

En este caso, mi invocable está leyendo desde un InputStream. Quiero asegurarme de que la transmisión esté cerrada si se llama a cancel() en la instancia Future (ver mi comentario en la respuesta de Gray). –

+0

¿Alguna vez 'conseguirás 'en el futuro? –

+0

Sí, eventualmente llamaré a get() sobre el futuro (si el futuro no fue cancelado). –

Cuestiones relacionadas