J'ai vu beaucoup de code invoquer la méthode Thread.currentThread.interrupt () dans le bloc catch, pourquoi?
Réponses
Trop de publicités?Ceci est fait afin de maintenir l'état.
Quand vous prenez l' InterruptException
et l'avaler, vous avez essentiellement de prévenir toute hausse des méthodes de niveau/thread groupes de remarquer l'interruption. Qui peut causer des problèmes.
En appelant Thread.currentThread.interrupt()
, vous définissez le drapeau d'interruption du fil, donc niveau supérieur gestionnaires d'interruption remarquent et peut gérer de manière appropriée.
Java de la Simultanéité dans la Pratique explique cela plus en détail dans le Chapitre 7.1.3: Répondre à l'Interruption. Sa règle est la suivante:
Seul le code qui implémente un fil de la politique d'interruption peut avaler une interruption de la demande. Les tâches à caractère général et de la bibliothèque de code ne devrait jamais avaler de l'interruption des demandes.
Je pense que cet exemple de code rend les choses un peu claires. La classe qui fait le travail:
public class InterruptedSleepingThread extends Thread {
@Override
public void run() {
doAPseudoHeavyWeightJob();
}
private void doAPseudoHeavyWeightJob() {
for (int i=0;i<Integer.MAX_VALUE;i++) {
//You are kidding me
System.out.println(i + " " + i*2);
//Let me sleep <evil grin>
if(Thread.currentThread().isInterrupted()) {
System.out.println("Thread interrupted\n Exiting...");
break;
}else {
sleepBabySleep();
}
}
}
/**
*
*/
protected void sleepBabySleep() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
La classe principale:
public class InterruptedSleepingThreadMain {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
InterruptedSleepingThread thread = new InterruptedSleepingThread();
thread.start();
//Giving 10 seconds to finish the job.
Thread.sleep(10000);
//Let me interrupt
thread.interrupt();
}
}
Essayez d'appeler une interruption sans rétablir l'état.
Note:
Comment puis-je arrêter un thread qui attend pour de longues périodes (par exemple, pour l'entrée)?
Pour que cette technique fonctionne, il est essentiel que toute méthode qui attrape une interruption exception et n'est pas préparé pour faire face immédiatement réaffirme l'exception. Nous disons réaffirme plutôt que renvoie, car il n'est pas toujours possible de relever de l'exception. Si la méthode qui attrape le InterruptedException n'est pas déclaré à jeter ce (vérifié) exception, alors il devrait "reinterrupt lui-même" avec l'incantation suivante:
Thread.currentThread().interrupt();
Cela garantit que le Thread va relancer la InterruptedException dès qu'il est capable.
Je le considère comme une mauvaise pratique ou au moins un peu risqué.
Généralement plus élevé au niveau des méthodes de ne pas effectuer d'opérations de blocage et qu'ils ne verront jamais, InterruptedException
. Si vous masque dans chaque endroit que vous effectuez interruptible opération, vous ne l'aura jamais.
La seule justification de l' Thread.currentThread.interrupt()
et de ne pas soulever toute autre exception ou de signalisation de demande d'interruption de toute autre manière (par exemple la création d' interrupted
variable locale de la variable dans le fil de la boucle principale) est la situation où vous ne pouvez vraiment pas faire n'importe quoi avec l'exception, comme dans l' finally
blocs.
Voir Péter Török réponse, si vous voulez mieux comprendre les implications de l' Thread.currentThread.interrupt()
appel.