Pourriez-vous expliquer ce que java.lang.Thread.interrupt()
fait une fois invoqué?
Pourriez-vous expliquer ce que java.lang.Thread.interrupt()
fait une fois invoqué?
Réponses:
Thread.interrupt()
définit l'état / l'indicateur interrompu du thread cible. Ensuite, le code exécuté dans ce thread cible PEUT interroger l'état interrompu et le gérer de manière appropriée. Certaines méthodes qui bloquent, par exemple, Object.wait()
peuvent consommer immédiatement l'état interrompu et lever une exception appropriée (généralement InterruptedException
)
L'interruption en Java n'est pas préventive. Autrement dit, les deux threads doivent coopérer afin de traiter correctement l'interruption. Si le thread cible n'interroge pas l'état interrompu, l'interruption est effectivement ignorée.
L'interrogation se produit via la Thread.interrupted()
méthode qui renvoie l'état interrompu du thread actuel ET efface cet indicateur d'interruption. Habituellement, le thread peut alors faire quelque chose comme lever InterruptedException.
EDIT (d'après les commentaires de Thilo): Certaines méthodes API ont intégré la gestion des interruptions. Du haut de ma tête, cela comprend.
Object.wait()
,, Thread.sleep()
etThread.join()
java.util.concurrent
structuresInterruptedException
, à la place ClosedByInterruptException
.EDIT (de la réponse de @ thomas-pornin à exactement la même question pour être complet)
L'interruption du fil est un moyen doux de pousser un fil. Il est utilisé pour donner aux fils une chance de sortir proprement , par opposition à Thread.stop()
cela, c'est plus comme tirer sur le fil avec un fusil d'assaut.
Qu'est-ce que l'interruption?
Une interruption est une indication pour 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. L'appel de Thread.interrupt définit ce drapeau. Lorsqu'un thread recherche une interruption en appelant la méthode statique Thread.interrupted, l'état d'interruption est effacé. Le Thread.isInterrupted non statique, qui est utilisé par un thread pour interroger l'état d'interruption d'un autre, ne modifie pas l'indicateur d'état d'interruption.
Citation de l' Thread.interrupt()
API :
Interrompt ce fil. Tout d'abord, la méthode checkAccess de ce thread est invoquée, ce qui peut provoquer la levée d'une SecurityException.
Si ce thread est bloqué lors d'une invocation des méthodes wait (), wait (long) ou wait (long, int) de la classe Object, ou des fonctions join (), join (long), join (long, int) , sleep (long) ou sleep (long, int), les méthodes de cette classe, puis son état d'interruption sera effacé et il recevra une InterruptedException.
Si ce thread est bloqué dans une opération d'E / S sur un canal interruptible, le canal sera fermé, l'état d'interruption du thread sera défini et le thread recevra une exception ClosedByInterruptException.
Si ce thread est bloqué dans un sélecteur, l'état d'interruption du thread sera défini et il reviendra immédiatement de l'opération de sélection, éventuellement avec une valeur non nulle, comme si la méthode de réveil du sélecteur était invoquée.
Si aucune des conditions précédentes n'est remplie, l'état d'interruption de ce thread sera défini.
Vérifiez ceci pour une compréhension complète à ce sujet:
http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Si le thread ciblé a attendu (en appelant wait()
, ou d'autres méthodes connexes qui font essentiellement la même chose, comme sleep()
), il sera interrompu, ce qui signifie qu'il cesse d'attendre ce qu'il attendait et reçoit une exception InterruptedException à la place.
C'est entièrement au thread lui-même (le code qui l'a appelé wait()
) de 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 s'arrêter. Mais encore une fois, ce n'est qu'une convention.
Pour être complet, en plus des autres réponses, si le thread est interrompu avant de se bloquer sur Object.wait(..)
ou Thread.sleep(..)
etc., cela équivaut à être interrompu immédiatement lors du blocage sur cette méthode , comme le montre l'exemple suivant.
public class InterruptTest {
public static void main(String[] 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");
}
}
Production:
$ 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 est parti Thread.sleep(..)
et fait le tour de la boucle, l'exception va toujours se produire. Il est donc parfaitement sûr de se fier à InterruptedException de façon fiable après que le thread a été interrompu :
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException ie) {
break;
}
}
Thread.interrupt()
définit le statut / indicateur interrompu du thread cible sur true, ce qui, lorsqu'il est vérifié à l'aide, Thread.interrupted()
peut aider à arrêter le thread sans fin. Voir http://www.yegor256.com/2015/10/20/interrupted-exception.html
L'interruption de thread est basée sur l' état d'interruption de l' indicateur . Pour chaque thread, la valeur par défaut du statut d'interruption est définie sur false . Chaque fois que la méthode interrupt () est appelée sur le thread, le statut d'interruption est défini sur true .
interruption de vide public ()
Interrompt ce fil.
À moins que le thread actuel ne s'interrompt, ce qui est toujours autorisé, la méthode checkAccess de ce thread est invoquée, ce qui peut provoquer la levée d'une SecurityException.
Si ce thread est bloqué lors d'une invocation des méthodes wait (), wait (long) ou wait (long, int) de la classe Object, ou des fonctions join (), join (long), join (long, int) , sleep (long) ou sleep (long, int), les méthodes de cette classe, puis son état d'interruption sera effacé et il recevra une InterruptedException.
Si ce thread est bloqué dans une opération d'E / S sur un canal interruptible, le canal sera fermé, l'état d'interruption du thread sera défini et le thread recevra une exception ClosedByInterruptException.
Si ce thread est bloqué dans un sélecteur, l'état d'interruption du thread sera défini et il reviendra immédiatement de l'opération de sélection, éventuellement avec une valeur non nulle, comme si la méthode de réveil du sélecteur était invoquée.
Si aucune des conditions précédentes n'est remplie, l'état d'interruption de ce thread sera défini.
L'interruption d'un thread qui n'est pas vivant n'a aucun effet.
Génère: SecurityException - si le thread actuel ne peut pas modifier ce thread
Une interruption est une indication pour 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
La méthode Thread.interrupt () définit l'indicateur interne «statut d'interruption». Habituellement, cet indicateur est vérifié par la méthode Thread.interrupted ().
Par convention, toute méthode qui existe via InterruptedException doit effacer l'indicateur d'état d'interruption.