2012-10-09 12 views
7

Qual è il modo corretto di gestire Thread.interrupted() in un Callable? Immagino che il callable debba lanciare un InterruptedException; ad esempio:Modo corretto per gestire Thread.interrupted() in 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; 
    } 
} 

È corretto oppure esiste un modo più appropriato di gestirlo? Grazie.

+3

L'unica vera fonte per spiegare 'InterruptedException' è [qui] (http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html). –

+0

L'ho letto prima, ma non parla di Callable. Ottimo articolo, però. –

risposta

6

Edit:

Dopo un po 'avanti e indietro, sembra che si vuole essere in grado di interrompere la vostra routine IO. Questo sembra un buon lavoro per alcune delle classi NIO InterrutibleChannel. Ad esempio, la lettura dal seguente numero BufferedReader è interrompibile e genera InterruptedIOException. Vedi qui per more examples of the NIO code.

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

Quindi, è possibile chiamare future.cancel() che interrompere il filo e causare IO per gettare un InterruptedIOException. Se ciò accade, potresti non catturare il IOException e lasciarlo fuoriuscire dal metodo call().


Se si desidera passare indietro al Future che il metodo call() è stata interrotta poi penso che gettando InterruptedException va bene. Un'altra opzione potrebbe essere solo return null; o qualche altro oggetto indicatore dal tuo metodo call(). Questo è tipicamente quello che faccio se un thread è stato interrotto.

Una cosa da ricordare è che se tiri call()InterruptedException, quando si fa un future.get() si getterà un ExecutionException e la causa di tale eccezione sta per essere un InterruptedException. Non essere confuso dal fatto che lo future.get() può anche lanciare uno InterruptedException se il get(long timeout, TimeUnit unit) è scaduto.

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

Se, tuttavia, future.cancel(true) si chiamava allora la future.get() sarà gettare un CancellationException invece.

+0

Fornirò un po 'più di contesto. Il mio codice in realtà non usa un ciclo while (vero) - sta leggendo da un InputStream personalizzato che controlla il valore di Thread.interrupted() in read (byte). Il metodo read() genera InterruptedException per garantire che il codice chiamante (che sta leggendo dal flusso) chiuda correttamente lo stream. –

+0

Si scopre che questo non funzionerà, dato che read() può solo lanciare IOException. Sembra che quello che voglio potrebbe essere InterruptedIOException. –

+0

Certo @Greg. Un'altra idea è usare un 'InterruptibleChannel' supportato da NIO. – Gray

1

Dipende in realtà da come si desidera che il thread sia in attesa su get(). Se non si desidera che il thread in attesa di avere un eccezione generata allora non si vuole throw new InterruptedException

Immaginate

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

}catch(InterruptedException em){ 

} 

Se si verifica alcuna eccezione che cosa ci si aspetta di essere? Nel tuo caso è un ExecutionException. Se non vuoi un ExecutionException allora non dovresti rilanciare l'InterruptedException.

+0

In questo caso, il mio callable sta leggendo da un InputStream. Voglio assicurarmi che lo stream sia chiuso se cancel() è chiamato nell'istanza Future (vedi il mio commento sulla risposta di Gray). –

+0

Ti capita mai di "avere" il futuro? –

+0

Sì, alla fine chiamerò get() sul futuro (se il futuro non è stato cancellato). –

Problemi correlati