Quand Thread.sleep de Java génère-t-il une exception 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.
Vous ne devriez généralement PAS ignorer l'exception. Jetez un coup d'œil au papier suivant:
Ne pas avaler les interruptions
Parfois, le lancement d'une exception 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 renvoyer une exception InterruptedException, mais vous ne souhaitez également rien faire. Lorsqu'une méthode de blocage détecte une interruption et lève une exception InterruptedException, elle supprime le statut interrompu. Si vous interceptez InterruptedException mais que vous ne pouvez pas le rediffuser, vous devez conserver la preuve que l'interruption s'est produite afin que le code situé en haut de 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 intercepterez InterruptedException sans le réexaminer, réinterromprez le thread en cours avant de le renvoyer.
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 le papier entier ici:
http://www.ibm.com/developerworks/Java/library/j-jtp05236/index.html?ca=drs-
Si un InterruptedException
est lancé, cela signifie que quelque chose veut interrompre (généralement mettre fin) à ce fil. Ceci est déclenché par un appel à la méthode threads interrupt()
. La méthode wait le détecte et jette un InterruptedException
afin que le code de capture puisse traiter la demande de résiliation immédiatement et ne doit pas attendre que le délai spécifié soit écoulé.
Si vous l'utilisez dans une application mono-thread (et également dans certaines applications multi-thread), cette exception ne sera jamais déclenchée. Ignorer cela en ayant une clause de capture vide, je ne le recommanderais pas. Le lancement de InterruptedException
efface l'état d'interruption du thread. Par conséquent, si l'information n'est pas gérée correctement, cette information est perdue. Par conséquent, je proposerais de lancer:
} 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);
}
... déclaration au bloc catch. Cela signifie fondamentalement que cela ne doit jamais arriver. Donc, si le code est réutilisé dans un environnement où cela pourrait arriver, il s'en plaindra.
La Java Newsletter des spécialistes (que je peux recommander sans réserve) avait un article intéressant à ce sujet , et comment gérer le InterruptedException
. Il vaut la peine de le lire et digérer.
Un moyen simple et solide de le gérer dans un code à thread unique serait de l'attraper et de le retransmettre dans une exception RuntimeException, afin d'éviter la nécessité de le déclarer pour chaque méthode.
Des méthodes comme sleep()
et wait()
de la classe Thread
pourraient renvoyer un InterruptedException
. Cela se produira si un autre thread
veut interrompre le thread
en attente ou en veille.