2013-07-24 12 views
6

Mentre si lavora su un progetto mi sono imbattuto in questo codice destinato ad un sistema di produzione:E 'sempre una cassetta di sicurezza di ignorare sempre InterruptedException chiamando sonno Discussione() in Java

public static void sleepUntil(long millisecondToWake) { 
    while (true) { 
     long currentMillisecond = System.currentTimeMillis(); 
     if (currentMillisecond >= millisecondToWake) { 
      break; 
     } 
     try { 
      Thread.sleep(millisecondToWake - currentMillisecond); 
     } 
     catch (InterruptedException ignoredException) { 
      // do nothing 
     } 
    } 
} 

Ho sempre attaccato alla base principio di non abbandonare mai eccezioni come esposte da Joshua Bloch in Java efficace e supportate dalla mia vasta esperienza di dover eseguire il debug del codice dove qualcun altro ha fatto cadere un'eccezione. Ad oggi, non ho trovato un caso in cui sia una buona idea (a volte l'osservazione dell'eccezione controllata e il lancio di un runtime sono debitamente ragionevoli ma non sto parlando di questi casi qui).

Grazie in anticipo per eventuali commenti.

+0

mai è una buona opzione lasciando un vuoto cattura. prima di tutto non noterai un malfunzionamento del tuo codice. leggi quando viene prodotta questa eccezione e scrivi il codice in attesa dell'eccezione. – logoff

+0

http://stackoverflow.com/q/824110/813951 –

risposta

4

Ecco un ottimo articolo su questo particolare eccezione:

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html

In sostanza, però, non dovrebbe essere ignorato, per lo meno il codice dovrebbe fare è diffondere l'interruzione:

catch (InterruptedException e) { 
    // Restore the interrupted status 
    Thread.currentThread().interrupt(); 
} 

L'autore non si preoccupa che il sonno del suo Thread sia interrotto (che è un valido motivo per ingoiare l'eccezione); tuttavia l'interruzione potrebbe essere richiesta altrove in una discussione che l'autore non sapeva o non pensava quando scriveva il suo codice:

se si intende o meno intervenire sulla richiesta di interrupt, si desidera comunque reinterruptlo thread corrente perché una singola richiesta di interruzione può avere più "destinatari". L'implementazione del thread di lavoro del pool di thread standard (ThreadPoolExecutor) è sensibile all'interruzione, pertanto l'interruzione di un'attività in esecuzione in un pool di thread potrebbe avere l'effetto di annullare l'attività e notificare il thread di esecuzione che il pool di thread si sta arrestando.

+0

Strano che l'esempio di codice non propaga l'eccezione. –

+0

Penso che l'idea sia che l'autore vuole che il thread si addormenti e non debba preoccuparsi di gestire l'eccezione. Non essere d'accordo o difenderlo. Solo sollecitando opinioni più istruite a riguardo. Ho letto l'articolo di IBM. In particolare, non affronta il caso del sonno.Se la cosa peggiore che può accadere è che JVM non può esistere fino a quando il sonno è finito, allora sospetto che l'autore di questo codice sia OK, ma mi chiedo se causerà problemi peggiori. Grazie! – codeotaku

+0

@JBNizet non è affatto strano. Non ho menzionato la propagazione dell'eccezione, ho detto propagare l'interruzione. – StuPointerException

3

Non sembra un approccio ragionevole in quello specifico esempio. In particolare, se un utente desidera uscire dal programma (ad esempio), la JVM si bloccherà fino a quando il tuo metodo di sospensione non sarà terminato, il che sembra irragionevole.

IMO, l'unica situazione in cui si può tranquillamente ignorare una InterruptedException è dove:

  • si ha il pieno controllo del thread in esecuzione il metodo, e
  • immediatamente uscita dopo l'eccezione viene ignorato.

In qualsiasi altra situazione, è necessario: ripristinare il flag interrotto ed uscire immediatamente.

Ad esempio, questo sarebbe ok:

//the task is local, nobody else can access it 
final Runnable localRunnable = new Runnable() { 
    public void run() { 
     //catch, ignore and exit immediately 
     try { Thread.sleep(10000); } catch (InterruptedException e) {} 
    } 
} 
//it is your own thread and you have full control over it 
new Thread(localRunnable).start(); 
+0

Oltre a bloccare un'uscita JVM immediata, ci sono altri cattivi risultati possibili? Che cosa segnala veramente InterruptedException? Nemmeno per me è chiaro. Grazie. – codeotaku

+0

interruzione @codeotaku è il meccanismo utilizzato in Java per chiedere a un thread di interrompere ciò che sta facendo. Ad esempio, se un thread sta scaricando un file di grandi dimensioni e interrompi quel thread, è necessario aspettarsi che interrompa il download, ripulisca le risorse (socket chiusi ecc.) Ed esci. Quando un'attività ignora le interruzioni, rende impossibile arrestarla. Ad esempio, ci sono molte domande su SO sulle librerie di terze parti che ignorano le interruzioni e le rendono molto ostili. L'unica soluzione in una situazione del genere è eseguire il codice nel proprio processo, il che complica inutilmente le cose ... – assylias

Problemi correlati