Quand Thread.sleep de Java lance-t-il InterruptedException?

110

Quand Thread.sleep de Java lance-t-il InterruptedException? Est-il prudent de l'ignorer? Je ne fais pas de multithreading. Je veux juste attendre quelques secondes avant de réessayer une opération.

Manki
la source
1
Cela dépend dans quel sens vous voulez dire «ignorer». InterruptedExceptionest une exception interceptée, de sorte que vous ne pouvez pas compiler à moins que vous gérez ou déclarer ce type d'exception sur une méthode qui rejoint ou dort Thread, ou des appels wait()sur Object.
8bitjunkie

Réponses:

41

Vous ne devez généralement PAS ignorer l'exception. Jetez un œil à l'article suivant:

N'avalez pas les interruptions

Parfois, lancer InterruptedException n'est pas une option, par exemple lorsqu'une tâche définie par Runnable appelle une méthode interruptible. Dans ce cas, vous ne pouvez pas relancer InterruptedException, mais vous ne voulez pas non plus ne rien faire. Lorsqu'une méthode de blocage détecte une interruption et lève InterruptedException, elle efface l'état d'interruption. Si vous interceptez InterruptedException mais que vous ne pouvez pas la relancer, vous devez conserver la preuve que l'interruption s'est produite afin que le code situé plus haut dans la pile d'appels puisse connaître l'interruption et y répondre s'il le souhaite. Cette tâche est accomplie en appelant interrupt () pour "réinterrompre" le thread actuel, comme indiqué dans le Listing 3. Au minimum, chaque fois que vous interceptez InterruptedException et ne le relancez pas, réinterrompez le thread actuel avant de revenir.

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();
         }
    }
}

Voir l'article entier ici:

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

Benny Bottema
la source
38

Si un InterruptedExceptionest jeté, cela signifie que quelque chose veut interrompre (généralement terminer) ce thread. Cela est déclenché par un appel à la interrupt()méthode threads . La méthode wait détecte cela et lève un InterruptedExceptionafin que le code catch puisse traiter la demande d'arrêt immédiatement et n'ait pas à attendre que le temps spécifié soit écoulé.

Si vous l'utilisez dans une application à un seul thread (et également dans certaines applications à plusieurs threads), cette exception ne sera jamais déclenchée. Je ne recommanderais pas de l'ignorer en ayant une clause catch vide. Le lancement du InterruptedExceptionefface l'état interrompu du thread, donc s'il n'est pas géré correctement, cette information est perdue. Par conséquent, je proposerais d'exécuter:

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

Ce qui rétablit cet état. Après cela, terminez l'exécution. Ce serait un comportement correct, même difficile jamais utilisé.

Ce qui pourrait être mieux est d'ajouter ceci:

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

... instruction au bloc catch. Cela signifie essentiellement que cela ne doit jamais arriver. Donc, si le code est réutilisé dans un environnement où cela pourrait arriver, il s'en plaindra.

chrétien
la source
5
Les assertions en Java sont désactivées par défaut . Il est donc préférable de simplement lancer un RuntimeException.
Evgeni Sergeev
11

La newsletter Java Specialists (que je peux recommander sans réserve) contenait un article intéressant à ce sujet , et comment gérer le InterruptedException. Cela vaut la peine d'être lu et digéré.

Brian Agnew
la source
1
Ça dit quoi?
theonlygusti le
5

Des méthodes comme sleep()et wait()de classe Threadpeuvent lancer un InterruptedException. Cela se produira si un autre threadsouhaite interrompre celui threadqui attend ou qui dort.

user7805041
la source
3

Un moyen solide et simple de le gérer dans un code à thread unique serait de l'attraper et de le retrow dans une RuntimeException, pour éviter d'avoir à le déclarer pour chaque méthode.

starblue
la source
-7

Le InterruptedExceptionest généralement jeté lorsqu'un sommeil est interrompu.

BrutalOst
la source
13
C'est faux, car ce n'est pas le sommeil lui-même qui est interrompu, mais le thread qui l'exécute. Interrompu est un état de thread. Cela conduit simplement à quitter la méthode du sommeil.
ubuntudroid