2012-10-10 17 views
13

qual è la procedura migliore per la gestione di InterruptedException s quando si utilizza Throwables.propagate (e) in Guava?Guava: Throwables.propagate e InterruptedException

Mi piace usare throw Throwables.propagate(e), in particolare nei metodi che non generano eccezioni controllate e dove la gestione delle eccezioni è responsabilità del chiamante. Ma non fa quello che mi aspetterei con InterruptedException.

io non voglio perdere il fatto che il filo è stato interrotto, così finisco scrivendo cose come:

public void run() { 
    Callable c = ...; 
    try { 
     c.call(); 
    } catch (InterruptedException e) { 
     Thread.currentThread().interrupt(); 
     throw Throwables.propagate(e); 
    } catch (Exception e) { 
     throw Throwables.propagate(e); 
    } 
} 

C'è un modo per fare questo in Guava? Esiste un modo (compatibile all'indietro ?!) per usare qualcosa come Throwables.propagate() che imposta il thread come interrotto, se sta avvolgendo e propagando un InterruptedException?

+1

Vorrei sollevarlo come una richiesta di funzionalità all'interno di Guava – artbristol

risposta

7

Convenientemente, abbiamo discusso questo internamente qualche tempo fa. Mi limiterò a copiare e incollare:

mio parere linea dura sulla Throwables.propagate(e) è che è fondamentalmente throw new RuntimeException(e) e che la gente di solito non dovrebbe farlo, proprio come di solito non dovrebbero scrivere throw new RuntimeException(e). (E se hanno intenzione di scriverlo, potrebbero anche scriverlo direttamente in modo che sia chiaro cosa sta succedendo.)

Il mio parere sulla linea dura su catch (Exception e) - di solito come le persone si mettono in questo pasticcio - è che di solito non dovrebbero farlo neanche loro. (Ovviamente ci sono casi in cui catch (Exception e) è ovviamente la cosa giusta da fare (fondamentalmente qualsiasi blocco catch di operazione di livello superiore), ma quelli sono ... ovvi.)

Il mio parere di linea dura su InterruptedException è che avere InterruptedException implementa Exception in questo modo viene interrotto esattamente in questo modo: richiede una gestione speciale che altre eccezioni no.

Il mio parere di linea dura sulla conversione di InterruptedException in un RuntimeException è "non farlo". (Questo, come gran parte delle altre cose che ho detto sopra, è controverso.)

Quindi, da un lato, non sono sicuro che ci sia qualcosa che possiamo fare per salvare propagate(). D'altra parte, forse è bello rendere il metodo un po 'meno cattivo.

nuovo Poi, considerare questo chiamante, che cattura ExecutionException e:

throw Throwables.propagate(e.getCause());

Sarebbe sbagliato interrompere il filo dei consumatori, così come sarebbe sbagliato gettare e.getCause() direttamente, perché l'interruzione era destinato per il thread di calcolo, non per il thread di consumo.

Sono propenso a lasciare propagate() da solo. (Come puoi probabilmente indovinare, sono personalmente incline a deprecarlo, ma questa è una discussione più ampia.)

+1

+1 punti interessanti. Sono stupito che le persone scrivano 'throw Throwables.propagate (e.getCause());'! La traccia dello stack sarebbe come se tutto fosse accaduto in un singolo thread! – artbristol

+1

Grazie, punti interessanti. +1 a InterruptedException che implementa l'eccezione in modo errato, ma Java è dove si trova. Penso che la conversione di InterruptedException in una RuntimeException sia talvolta essenziale: se la mia firma del metodo viene riparata da un'interfaccia esterna (quindi non posso lanciare InterruptedException), e la mia operazione è stata interrotta (quindi non posso adempiere al mio contratto), I deve fare un'eccezione Quale altra opzione ragionevole è lì oltre a impostare il thread come interrotto e lanciare un RuntimeException? –

+4

Per scrivere 'throw new RuntimeException (e)' invece, è fastidioso che il rumore abbia un'eccezione che avvolge l'eccezione (specialmente quando non aggiunge nulla di utile, come un messaggio aggiuntivo sul contesto corrente). Ovunque sia possibile evitare il rumore (ad es. È già un'eccezione non controllata), allora ottimo. C'è una scuola di pensiero che le API dovrebbero utilizzare le eccezioni non controllate ove possibile. Anche se non si compra questo argomento, si devono ancora implementare le interfacce di altre persone scritte in quel modo. Quindi per favore non deprecate 'Throwables.propagate (e)'! –