Que fait java.lang.Thread.interrupt ()?

Pouvez-vous expliquer ce que fait java.lang.Thread.interrupt() lorsqu’il est appelé?

Thread.interrupt() définit le statut / drapeau interrompu du thread cible. Ensuite, le code s’exécutant dans ce thread cible PEUT interroger le statut interrompu et le gérer de manière appropriée. Certaines méthodes qui bloquent comme Object.wait() peuvent consumr immédiatement le statut interrompu et lancer une exception appropriée (généralement InterruptedException )

L’interruption en Java n’est pas préemptive. En d’autres termes, les deux threads doivent coopérer pour traiter correctement l’interruption. Si le thread cible n’interroge pas le statut interrompu, l’interruption est effectivement ignorée.

L’ Thread.interrupted() se produit via la méthode Thread.interrupted() qui renvoie le statut interrompu du thread en cours ET efface cet indicateur d’interruption. Habituellement, le thread peut faire quelque chose comme lancer InterruptedException.

EDIT (à partir des commentaires Thilo): Certaines méthodes API ont intégré la gestion des interruptions. Du haut de ma tête cela inclut.

  • Object.wait()/Thread.sleep()
  • La plupart des structures java.util.concurrent
  • Java NIO (mais pas java.io) et il n’utilise PAS InterruptedException , à la place de ClosedByInterruptException .

EDIT (de la réponse de @ thomas-pornin à la même question pour être complet)

L’interruption du fil est un moyen doux de décaler un fil. Il est utilisé pour donner aux threads une chance de sortir proprement , contrairement à Thread.stop() qui ressemble plus à un thread avec un fusil d’assaut.

Qu’est-ce que l’interruption?

Une interruption indique à un thread qu’il doit arrêter ce qu’il fait et faire autre chose. C’est au programmeur de décider exactement comment un thread répond à une interruption, mais il est très courant que le thread se termine.

Comment est-il mis en œuvre?

Le mécanisme d’interruption est implémenté à l’aide d’un indicateur interne appelé état d’interruption. Invoquer Thread.interrupt définit cet indicateur. Lorsqu’un thread recherche une interruption en appelant la méthode statique Thread.interrupted, l’état de l’interruption est effacé. Le Thread.isInterrupted non statique, utilisé par un thread pour interroger le statut d’interruption d’un autre, ne modifie pas l’indicateur d’état d’interruption.

Citation de Thread.interrupt() API :

Interrompt ce fil. Tout d’abord, la méthode checkAccess de ce thread est appelée, ce qui peut provoquer une exception SecurityException.

Si ce thread est bloqué dans une invocation des méthodes wait (), wait (long), ou wait (long, int) de la classe Object, ou de la jointure (), join (long), join (long, int) , sleep (long), ou sleep (long, int), les méthodes de cette classe, puis son statut d’interruption sera effacé et il recevra une exception InterruptedException.

Si ce thread est bloqué dans une opération d’E / S sur un canal interruptible, le canal sera fermé, le statut d’interruption du thread sera défini et le thread recevra une exception ClosedByInterruptException.

Si ce thread est bloqué dans un sélecteur, le statut d’interruption du thread sera défini et il retournera immédiatement à l’opération de sélection, éventuellement avec une valeur différente de zéro, comme si la méthode de réveil du sélecteur était appelée.

Si aucune des conditions précédentes n’est vérifiée, le statut d’interruption de ce thread sera défini.

Vérifiez ceci pour une compréhension complète de la même chose:

http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

Pour être complet, en plus des autres réponses, si le thread est interrompu avant qu’il ne bloque sur Object.wait(..) ou Thread.sleep(..) etc., cela équivaut à être immédiatement interrompu lors du blocage sur cette méthode. , comme le montre l’exemple suivant.

 public class InterruptTest { public static void main(Ssortingng[] args) { Thread.currentThread().interrupt(); printInterrupted(1); Object o = new Object(); try { synchronized (o) { printInterrupted(2); System.out.printf("A Time %d\n", System.currentTimeMillis()); o.wait(100); System.out.printf("B Time %d\n", System.currentTimeMillis()); } } catch (InterruptedException ie) { System.out.printf("WAS interrupted\n"); } System.out.printf("C Time %d\n", System.currentTimeMillis()); printInterrupted(3); Thread.currentThread().interrupt(); printInterrupted(4); try { System.out.printf("D Time %d\n", System.currentTimeMillis()); Thread.sleep(100); System.out.printf("E Time %d\n", System.currentTimeMillis()); } catch (InterruptedException ie) { System.out.printf("WAS interrupted\n"); } System.out.printf("F Time %d\n", System.currentTimeMillis()); printInterrupted(5); try { System.out.printf("G Time %d\n", System.currentTimeMillis()); Thread.sleep(100); System.out.printf("H Time %d\n", System.currentTimeMillis()); } catch (InterruptedException ie) { System.out.printf("WAS interrupted\n"); } System.out.printf("I Time %d\n", System.currentTimeMillis()); } static void printInterrupted(int n) { System.out.printf("(%d) Am I interrupted? %s\n", n, Thread.currentThread().isInterrupted() ? "Yes" : "No"); } } 

Sortie:

 $ javac InterruptTest.java $ java -classpath "." InterruptTest (1) Am I interrupted? Yes (2) Am I interrupted? Yes A Time 1399207408543 WAS interrupted C Time 1399207408543 (3) Am I interrupted? No (4) Am I interrupted? Yes D Time 1399207408544 WAS interrupted F Time 1399207408544 (5) Am I interrupted? No G Time 1399207408545 H Time 1399207408668 I Time 1399207408669 

Implication: si vous bouclez comme suit et que l’interruption se produit au moment exact où le contrôle a quitté Thread.sleep(..) et Thread.sleep(..) autour de la boucle, l’exception doit toujours se produire. Il est donc parfaitement sûr que l’exception InterruptedException soit déclenchée de manière fiable après l’interruption du thread :

 while (true) { try { Thread.sleep(10); } catch (InterruptedException ie) { break; } } 

Si le thread ciblé a attendu (en appelant wait() , ou d’autres méthodes apparentées qui font essentiellement la même chose, comme sleep() ), il sera interrompu, ce qui signifie qu’il arrête d’attendre ce qu’il attendait et recevez une exception InterruptedException à la place.

Il appartient entièrement au thread lui-même (le code appelé wait() ) pour décider quoi faire dans cette situation. Il ne termine pas automatiquement le thread.

Il est parfois utilisé en combinaison avec un indicateur de terminaison. Lorsqu’il est interrompu, le thread peut vérifier cet indicateur, puis se fermer. Mais encore une fois, ceci n’est qu’une convention.

Interruption de void publique ()

Interrompt ce fil.

À moins que le thread en cours ne s’interrompt, ce qui est toujours autorisé, la méthode checkAccess de ce thread est appelée, ce qui peut provoquer une exception SecurityException.

Si ce thread est bloqué dans une invocation des méthodes wait (), wait (long), ou wait (long, int) de la classe Object, ou de la jointure (), join (long), join (long, int) , sleep (long), ou sleep (long, int), les méthodes de cette classe, puis son statut d’interruption sera effacé et il recevra une exception InterruptedException.

Si ce thread est bloqué dans une opération d’E / S sur un canal interruptible, le canal sera fermé, le statut d’interruption du thread sera défini et le thread recevra une exception ClosedByInterruptException.

Si ce thread est bloqué dans un sélecteur, le statut d’interruption du thread sera défini et il retournera immédiatement à l’opération de sélection, éventuellement avec une valeur différente de zéro, comme si la méthode de réveil du sélecteur était appelée.

Si aucune des conditions précédentes n’est vérifiée, le statut d’interruption de ce thread sera défini.

Interrompre un thread qui n’est pas en vie n’a pas besoin d’avoir d’effet.

Lève: SecurityException – si le thread actuel ne peut pas modifier ce thread

Thread.interrupt() définit Thread.interrupt() le statut / flag interrompu du thread cible qui, lorsqu’il est coché avec Thread.interrupted() peut aider à arrêter le thread sans fin. Refer http://www.yegor256.com/2015/10/20/interrupted-exception.html

L’interruption du fil est basée sur l’ état d’interruption du drapeau. Pour chaque thread, la valeur par défaut du statut d’interruption est définie sur false . Chaque fois que la méthode interruption () est appelée sur le thread, le statut d’interruption est défini sur true .

  1. Si interruption status = true (interrupt () déjà appelé sur le thread), ce thread particulier ne peut pas s’endormir. Si sleep est appelé, cette exception interrompue est renvoyée. Après avoir relancé l’exception à nouveau, l’indicateur est défini sur false.
  2. Si le thread dort déjà et que interrupt () est appelé, le thread sortira de son état de veille et lancera une exception interrompue.

Une interruption indique à un thread qu’il doit arrêter ce qu’il fait et faire autre chose. C’est au programmeur de décider exactement comment un thread répond à une interruption, mais il est très courant que le thread se termine. Une très bonne référence: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html