1. Einführung
In diesem Artikel werden einige Wissenspunkte über den Interrupt -Mechanismus in Java multithreading aufgezeichnet. Es besteht hauptsächlich aus dem Unterschied zwischen den Methoden der Stop -Methode unterbrochen () und isinrupted () und führt eine einfache Analyse aus der Implementierung des Quellcode durch.
Es gibt 3 Möglichkeiten, um laufende Threads in Java zu beenden
① Der Thread beendet normalerweise, dh die Run () -Methode wurde ausgeführt
② Verwenden Sie die Stop () -Methode in der Thread -Klasse, um den Faden zwangs zu beenden. Die Stop () -Methode ist jedoch abgelaufen und wird nicht empfohlen, sie zu verwenden
③use Interrupt -Mechanismus
Es gibt nichts zu tun, wenn der Thread normal ausgeht. Der Interrupt -Mechanismus wird nachstehend ausführlich eingeführt. Schauen wir uns zunächst den Quellcode der Stop () -Methode an. Der Schlüssel sind die Kommentare zum Quellcode. Es erklärt, warum Stop () nicht sicher ist, welcher Thread wird von der Stop () -Methode gestoppt?
/*** erzwingt den Thread, die Ausführung einzustellen. Dies kann dazu führen, dass ein* <Code> SecurityException </code> erhöht wird (im aktuellen Thread). <Code> SecurityException </code> (im aktuellen Thread). <Code> ThreadDeath </code>, es sei denn, es muss einen außergewöhnlichen* Reinigungsvorgang ausführen (Beachten Sie, dass das Werfen von* <Code> ThreadDeath </code> entsteht <code> Schließlich </code> Klauseln von* <Code> Versuchen Sie, </Code> Voraussetzungen vor dem Thread* offiziell zu fällen). Wenn ein <code> catch </code> -Klausel ein* <Code> ThreadDeath </code> Objekt fängt, ist es wichtig, das* Objekt so zu überdenken, dass der Thread tatsächlich stirbt. Der aktuelle Thread kann diesen Thread nicht ändern. Stoppen Sie einen Thread mit* Thread.Stop veranlasst ihn, alle Monitore zu entsperren, die er gesperrt hat (als natürliche Folge des ungeprüften* <Code> ThreadDeath </code> Ausnahme, der den Stapel nach oben ausbreitet). Wenn* eines der zuvor durch diese Monitore geschützten Objekte in einem inkonsistenten Zustand war, werden die beschädigten Objekte für* andere Threads sichtbar, was möglicherweise zu willkürlicher Verhalten führt. Viele* Verwendungen von <Code> Stop </code> sollten durch Code ersetzt werden, die einfach* eine Variable ändern, um anzuzeigen, dass der Ziel -Thread* aufhören sollte, das Laufen zu lenken. Der Ziel -Thread sollte diese Variable* regelmäßig überprüfen und ordnungsgemäß aus seiner Run -Methode zurückkehren, wenn die Variable angibt, dass er nicht mehr ausgeführt werden soll. Wenn der* Ziel -Thread auf lange Zeiträume wartet (beispielsweise in einer Bedingungsvariablen*), sollte die Methode <Code> Interrupt </code> verwendet werden, um das Warten zu unterbrechen. Veraltet? </a>.*/@DeprescatedPublic Final void stop () {stop (neuer ThreadDeath ());}Wie oben kommentiert, zeigen die Zeilen 9 bis 16 an, dass die Stop () -Methode "andere Threads" stoppen kann. Der Thread, der den Thread ausführt.
wie:
public static void main (String [] args) {mythead thread = new MyThread ... // .... thread.stop (); // ..}In der Hauptmethode ist der aktuelle Thread der Hauptfaden. Es wird in Zeile 4 ausgeführt und möchte den "anderen Thread" -Thread anhalten. Dieser andere Thread ist der Thread, der durch das Thread -Objekt der neuen MyThread -Klasse dargestellt wird.
Zeilen 21 bis 23 zeigen, dass ein Thread, der noch nicht gestartet wurde, gestoppt werden kann. Sein Effekt ist: Wenn der Faden beginnt, endet er sofort.
Die Kommentare nach Zeile 48 zeigen tief, warum die Stop () -Methode veraltet ist! Warum es unsicher ist.
Zum Beispiel hat Threada -Thread Monitore, die für den Schutz bestimmter kritischer Ressourcen verantwortlich sind, z. B. die Höhe der Bankübertragungen. Wenn der Übertragungsprozess im Gange ist, ruft der Haupt -Thread die Methode threada.stop () auf. Infolgedessen wird der Monitor freigegeben, und die Ressourcen, die er schützt (die Übertragungsmenge), dürften inkonsistent sind. Zum Beispiel hat Konto A um 100 gesunken, während Konto B nicht um 100 erhöht wurde.
Zweitens Interrupt -Mechanismus
Es gibt zu viele Details darüber, wie der Interrupt -Mechanismus in Java korrekt verwendet wird. Sowohl die Methoden unterbrochen () als auch isinrupted () reflektieren, ob sich der aktuelle Thread in einem unterbrochenen Zustand befindet.
① unterbrochen ()
/*** Tests, ob der aktuelle Thread unterbrochen wurde. Der unterbrochene Status </i> des Threads wird nach dieser Methode gelöscht. In anderen Worten, wenn diese Methode zweimal nacheinander aufgerufen würde, würde der zweite Anruf falsch zurückkehren (es sei denn, der aktuelle Thread wurde erneut unterbrochen, nachdem der erste Anruf seinen unterbrochenen Status gelöscht hatte und bevor der zweite Anruf ihn untersucht hatte). Interrupted;* <Code> false </code> ansonsten.* @see #Interrupted ()* @revised.*/public static boolean interrupted () {return CurrentThread (). isinterrupted (true);}Aus den Kommentaren im Quellcode wird der Interrupt -Status des aktuellen Threads getestet, und diese Methode löscht den Interrupt -Status.
②isinterrupted ()
/*** Tests, ob dieser Thread unterbrochen wurde. Der unterbrochene <i> unterbrochene* Status </i> des Threads ist von dieser Methode nicht beeinflusst. isInterrupted () {return is unterruppt (false);}Wie aus den Quellcode -Kommentaren ersichtlich ist, löscht die Methode is interrupted () den Interrupt -Status nicht.
③Difference zwischen unterbruptem () Methode und isinrupted () -Methode
Wie aus dem Quellcode ersichtlich ist, werden beide Methoden als Issinruption (boolean klare Infruptd) bezeichnet, außer dass einer mit dem Parameter wahr und der andere mit dem Parameter falsch ist.
/*** Tests, wenn ein Thread unterbrochen wurde. Der unterbrochene Zustand* wird zurückgesetzt oder nicht auf dem Wert von ClearEnrupted, der übergeben wird.
Der erste Unterschied besteht daher darin, dass einer das Interrupt -Flag -Bit löscht und der andere das Interrupt -Flag -Bit nicht löscht.
Nachdem Sie den Quellcode analysiert haben, können Sie den zweiten Unterschied in der Return -Anweisung sehen:
public static boolean interbrupted () {return CurrentThread (). Ist unterbrochen (true);}/**********************/public boolean isinterrupted () {return is unterruppt (falsch);};};};};};};};Interrupted () testet den unterbrochenen Zustand des aktuellen Threads. Das isinrupted () testet den Thread, das durch das Objekt dargestellt wird, das die Methode aufruft. Eines ist eine statische Methode (sie testet den Interrupt -Status des aktuellen Threads) und die andere ist eine Instanzmethode (sie testet den Interrupt -Status des Threads, der durch das Instanzobjekt dargestellt wird).
Das Folgende ist ein spezifisches Beispiel, um diesen Unterschied weiter zu klären.
Es gibt eine benutzerdefinierte Thread -Klasse wie folgt:
öffentliche Klasse MyThread erweitert Thread {@Overridepublic void run () {super.run (); für (int i =; i <; i ++) {System.out.println ("i =" + (i +));}}}}}}}}}}}}}Schauen wir uns zunächst das Beispiel der Interrupted () -Methode an:
public class run {public static void main (String [] args) {try {mythead thread = new Mythead (); thread.start (); thread.sleep (); thread.interrupt (); // thread.currentThread (). Interrupt (); System.out.println ("stop? // ...Zeile 5 startet den Thread -Thread, und Zeile 6 macht den Hauptfadenschlaf für 1 Sekunde, so dass der Thread -Thread die Möglichkeit hat, die CPU -Ausführung zu erhalten.
Nachdem der Hauptfaden für 1s geschlafen hat, wird die Ausführung in Zeile 7 fortgesetzt und anfordern, den Thread -Thread zu unterbrechen.
In Zeile 9 Tests, ob sich der Faden in einem unterbrochenen Zustand befindet. Welcher Thread wird hier getestet? ? ? Die Antwort ist der Haupt -Thread. Weil:
(1) Interrupted () testet den Interruptstatus des aktuellen Threads
(2) Der Haupt -Thread führt die 9. Zeilenanweisung aus, sodass der Haupt -Thread der aktuelle Thread ist
Schauen wir uns das Beispiel der Methode isInterrupted () an:
public class run {public static void main (String [] args) {try {myThread thread = new mythead (); thread.start (); thread.sleep (); thread.interrupt (); System.out.println ("Halt es an?In Zeile 8 ist die vom Thread -Objekt aufgerufene Methode is unterruppte (). Daher wird der durch das Threadobjekt dargestellte Interrupt -Status des Threads getestet. Da in Zeile 7 der Haupt -Thread den Thread -Thread unterbricht, lautet das Ergebnis in Zeile 8: True