Quando Thread.sleep di Java genera InterruptException?


110

Quando Thread.sleep di Java genera InterruptException? È sicuro ignorarlo? Non sto facendo alcun multithreading. Voglio solo aspettare qualche secondo prima di ritentare qualche operazione.



1
Dipende dal senso in cui intendi "ignorare". InterruptedExceptionè un'eccezione catturato, quindi non è possibile compilare a meno che non si gestisce o dichiarare questo tipo di eccezione di una metodica che unisce o può ospitare un Threado chiamate wait()su Object.
8bitjunkie

Risposte:


41

In genere NON dovresti ignorare l'eccezione. Dai un'occhiata al seguente documento:

Non ingoiare interruzioni

A volte la generazione di InterrruptException non è un'opzione, ad esempio quando un'attività definita da Runnable chiama un metodo interrompibile. In questo caso, non puoi lanciare nuovamente InterrruptException, ma non vuoi nemmeno fare nulla. Quando un metodo di blocco rileva l'interruzione e genera InterructedException, cancella lo stato di interruzione. Se si rileva InterruptException ma non è possibile rilanciarla, è necessario conservare la prova che l'interruzione si è verificata in modo che il codice più in alto nello stack di chiamate possa apprendere l'interruzione e rispondere se lo desidera. Questa operazione viene eseguita chiamando interrupt () per "reinterrompere" il thread corrente, come mostrato nel Listato 3. Per lo meno, ogni volta che si cattura InterruptException e non si lancia di nuovo, si interrompe il thread corrente prima di tornare.

public class TaskRunner implements Runnable {
    private BlockingQueue<Task> queue;

    public TaskRunner(BlockingQueue<Task> queue) { 
        this.queue = queue; 
    }

    public void run() { 
        try {
             while (true) {
                 Task task = queue.take(10, TimeUnit.SECONDS);
                 task.execute();
             }
         }
         catch (InterruptedException e) { 
             // Restore the interrupted status
             Thread.currentThread().interrupt();
         }
    }
}

Vedi l'intero documento qui:

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-


38

Se InterruptedExceptionviene lanciato significa che qualcosa vuole interrompere (di solito terminare) quel thread. Ciò viene attivato da una chiamata al interrupt()metodo thread . Il metodo wait lo rileva e genera un fileInterruptedException modo che il codice di cattura possa gestire immediatamente la richiesta di terminazione e non deve attendere fino allo scadere del tempo specificato.

Se lo usi in un'app a thread singolo (e anche in alcune app multi-thread), tale eccezione non verrà mai attivata. Ignorarlo avendo una clausola di cattura vuota non lo consiglierei. Il lancio del messaggio InterruptedExceptioncancella lo stato interrotto del thread, quindi se non gestito correttamente quell'informazione va persa. Pertanto proporrei di eseguire:

} catch (InterruptedException e) {
  Thread.currentThread().interrupt();
  // code for stopping current task so thread stops
}

Che imposta di nuovo quello stato. Dopodiché, termina l'esecuzione. Questo sarebbe un comportamento corretto, anche duro mai usato.

Quello che potrebbe essere meglio è aggiungere questo:

} catch (InterruptedException e) {
  throw new RuntimeException("Unexpected interrupt", e);
}

... dichiarazione al blocco catch. Ciò significa fondamentalmente che non deve mai accadere. Quindi, se il codice viene riutilizzato in un ambiente in cui potrebbe accadere, se ne lamenterà.


5
Le asserzioni in Java sono disattivate per impostazione predefinita . Quindi è meglio lanciare un file RuntimeException.
Evgeni Sergeev


5

Metodi come sleep()e wait()di classe Threadpotrebbero generare un file InterruptedException. Questo accadrà se qualcun altro threadvolesse interrompere threadciò che sta aspettando o dormendo.


3

Un modo semplice e solido per gestirlo in codice a thread singolo sarebbe quello di catturarlo e retrowarlo in una RuntimeException, per evitare la necessità di dichiararlo per ogni metodo.


-7

Di InterruptedExceptionsolito viene lanciato quando un sonno viene interrotto.


13
È sbagliato, poiché non è il sonno stesso che viene interrotto, ma il Thread che lo esegue. Interrotto è uno stato del thread. Porta solo all'uscita dal metodo sleep.
ubuntudroid
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.