Was macht java.lang.Thread.interrupt ()?

Können Sie erklären, was java.lang.Thread.interrupt() beim Aufruf ausführt?

Thread.interrupt() setzt den unterbrochenen Status / Flag des Ziel-Threads. Dann kann Code, der in diesem Ziel-Thread läuft, den unterbrochenen Status abfragen und entsprechend behandeln. Einige Methoden, die beispielsweise Object.wait() blockieren, können den unterbrochenen Status sofort verwenden und eine entsprechende Ausnahme Object.wait() (normalerweise InterruptedException ).

Unterbrechung in Java ist nicht präventiv. Anders ausgedrückt müssen beide Threads zusammenarbeiten, um den Interrupt ordnungsgemäß zu verarbeiten. Wenn der Ziel-Thread den unterbrochenen Status nicht abfragt, wird der Interrupt effektiv ignoriert.

Das Thread.interrupted() erfolgt über die Thread.interrupted() -Methode, die den unterbrochenen Status des aktuellen Threads zurückgibt UND dieses Interrupt-Flag löscht. In der Regel kann der Thread dann etwas wie InterruptedException auslösen.

EDIT (von Thilo kommentiert): Einige API-Methoden haben Interrupt-Handling eingebaut. Das schließt von oben meinen Kopf mit ein.

  • Object.wait()/Thread.sleep()
  • Die meisten java.util.concurrent Strukturen
  • Java NIO (aber nicht java.io) und es verwendet keine InterruptedException , stattdessen ClosedByInterruptException .

EDIT (von @ thomas-pornins Antwort auf genau die gleiche Frage nach Vollständigkeit)

Fadenunterbrechung ist eine sanfte Methode, um einen Faden zu stupsen. Es wird verwendet, um Threads eine Chance zu geben, sauber zu Thread.stop() , im Gegensatz zu Thread.stop() , das mehr wie das Erschießen des Threads mit einem Sturmgewehr ist.

Was ist Interrupt?

Ein Interrupt ist ein Hinweis für einen Thread, dass er aufhören soll, was er tut, und etwas anderes tun. Es ist Sache des Programmierers, genau zu entscheiden, wie ein Thread auf einen Interrupt reactjs, aber es ist sehr üblich, dass der Thread beendet wird.

Wie wird es umgesetzt?

Der Unterbrechungsmechanismus wird unter Verwendung eines internen Merkers, der als Unterbrechungsstatus bekannt ist, implementiert. Der Aufruf von Thread.interrupt setzt dieses Flag. Wenn ein Thread nach einem Interrupt sucht, indem er die statische Methode Thread.interrupted aufruft, wird der Interrupt-Status gelöscht. Das nicht statische Thread.isInterrupted, das von einem Thread verwandt wird, um den Interrupt-Status eines anderen abzufragen, ändert das Interrupt-Statusflag nicht.

Zitat aus der Thread.interrupt() API :

Unterbricht diesen Thread. Zuerst wird die checkAccess-Methode dieses Threads aufgerufen, wodurch möglicherweise eine SecurityException ausgetriggers wird.

Wenn dieser Thread bei einem Aufruf der Methoden wait (), wait (long) oder wait (long, int) der Object-class oder von join (), join (long), join (long, int) blockiert wird , sleep (long) oder sleep (long, int), Methoden dieser class, dann wird der Interrupt-Status gelöscht und es wird eine InterruptedException empfangen.

Wenn dieser Thread in einer E / A-Operation auf einem unterbrechbaren Kanal blockiert wird, wird der Kanal geschlossen, der Unterbrechungsstatus des Threads wird festgelegt und der Thread erhält eine ClosedByInterruptException.

Wenn dieser Thread in einem Selector blockiert ist, wird der Interrupt-Status des Threads gesetzt, und er kehrt sofort von der Auswahloperation zurück, möglicherweise mit einem Wert ungleich Null, so als ob die Wakeup-Methode des Selektors aufgerufen würde.

Wenn keine der vorherigen Bedingungen zutrifft, wird der Interrupt-Status dieses Threads gesetzt.

Überprüfen Sie dies für das vollständige Verständnis über das gleiche:

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

Der Vollständigkeit Object.wait(..) zusätzlich zu den anderen Antworten, wenn der Thread unterbrochen wird, bevor er bei Object.wait(..) oder Thread.sleep(..) usw. blockiert wird, dies gleichbedeutend damit, dass er sofort beim Blockieren dieser Methode unterbrochen wird , wie das folgende Beispiel zeigt.

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

Ausgabe:

 $ 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 

Implikation: Wenn Sie wie folgt eine Schleife Thread.sleep(..) und der Interrupt genau zu dem Zeitpunkt auftritt, an dem die Steuerung Thread.sleep(..) und die Schleife Thread.sleep(..) , tritt die Ausnahme immer noch auf. Es ist also absolut sicher, sich darauf zu verlassen, dass die InterruptedException zuverlässig ausgetriggers wird, nachdem der Thread unterbrochen wurde :

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

Wenn der angezielte Thread gewartet hat (durch Aufrufen von wait() oder durch andere verwandte Methoden, die im Wesentlichen dasselbe tun, z. B. sleep() ), wird er unterbrochen, dh er wartet nicht mehr auf das, worauf er gewartet hat erhalten stattdessen eine InterruptedException.

Es liegt ganz an dem Thread selbst (der Code, der wait() ) zu entscheiden, was in dieser Situation zu tun ist. Der Thread wird nicht automatisch beendet.

Es wird manchmal in Kombination mit einem Abschlussflag verwendet. Bei einer Unterbrechung könnte der Thread dieses Flag überprüfen und sich dann selbst schließen. Aber auch das ist nur eine Konvention.

Öffentlicher ungültiger Interrupt ()

Unterbricht diesen Thread.

Wenn sich der aktuelle Thread nicht selbst unterbricht, was immer zulässig ist, wird die checkAccess-Methode dieses Threads aufgerufen, wodurch möglicherweise eine SecurityException ausgetriggers wird.

Wenn dieser Thread bei einem Aufruf der Methoden wait (), wait (long) oder wait (long, int) der Object-class oder von join (), join (long), join (long, int) blockiert wird , sleep (long) oder sleep (long, int), Methoden dieser class, dann wird der Interrupt-Status gelöscht und es wird eine InterruptedException empfangen.

Wenn dieser Thread in einer E / A-Operation auf einem unterbrechbaren Kanal blockiert wird, wird der Kanal geschlossen, der Unterbrechungsstatus des Threads wird festgelegt und der Thread erhält eine ClosedByInterruptException.

Wenn dieser Thread in einem Selector blockiert ist, wird der Interrupt-Status des Threads gesetzt, und er kehrt sofort von der Auswahloperation zurück, möglicherweise mit einem Wert ungleich Null, so als ob die Wakeup-Methode des Selektors aufgerufen würde.

Wenn keine der vorherigen Bedingungen zutrifft, wird der Interrupt-Status dieses Threads gesetzt.

Das Unterbrechen eines Threads, der nicht aktiv ist, muss keinen Effekt haben.

Auslöser: SecurityException – wenn der aktuelle Thread diesen Thread nicht ändern kann

Thread.interrupt() setzt den unterbrochenen Status / Flag des Thread.interrupted() auf “true”, was bei der Überprüfung mit Thread.interrupted() helfen kann, den Endlos-Thread zu stoppen. Siehe http://www.yegor256.com/2015/10/20/interrupted-exception.html

Die Thread-Unterbrechung basiert auf dem Flag- Interrupt-Status . Für jeden Thread ist der Standardwert des Interrupt-Status auf ” false” gesetzt . Wenn die interrupt () – Methode im Thread aufgerufen wird, wird der Interrupt-Status auf ” true” gesetzt .

  1. Wenn interrupt status = true (interrupt () bereits Thread aufgerufen), kann dieser bestimmte Thread nicht in den Ruhezustand wechseln. Wenn der Thread aufgerufen wird, wird die unterbrochene Ausnahme ausgetriggers. Nach dem Auslösen der Ausnahme wird das Flag erneut auf false gesetzt.
  2. Wenn der Thread bereits inaktiv ist und interrupt () aufgerufen wird, wird der Thread aus dem Ruhezustand wechseln und die unterbrochene Ausnahme auslösen.

Ein Interrupt ist ein Hinweis für einen Thread, dass er aufhören soll, was er tut, und etwas anderes tun. Es ist Sache des Programmierers, genau zu entscheiden, wie ein Thread auf einen Interrupt reactjs, aber es ist sehr üblich, dass der Thread beendet wird. Eine sehr gute Referenz: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html