Thread Start:
1. Beschreibung des Unterschieds zwischen start () und run ()
start (): Seine Funktion besteht darin, einen neuen Thread zu starten, und der neue Thread führt die entsprechende Run () -Methode aus. start () kann nicht wiederholt aufgerufen werden.
run (): run () kann wiederholt genauso wie gewöhnliche Mitgliedsmethoden aufgerufen werden. Wenn Sie Run () getrennt anrufen, wird run () im aktuellen Thread ausgeführt und der neue Thread wird nicht gestartet!
Das Folgende ist ein Code zu erklären.
Klasse myThread erweitert Thread {public void run () {...}}; MyThread myThread = new myThread (); mythead.start () startet einen neuen Thread und führt die Run () -Methode im neuen Thread aus.
MyThread.run () führt die Run () -Methode direkt im aktuellen Thread aus und startet keinen neuen Thread zum Run ().
2. Beispiel für den Unterschied zwischen start () und run ()
Nachfolgend zeigen Sie den Unterschied zwischen ihnen mit einem einfachen Beispiel. Der Quellcode lautet wie folgt:
// Demo.javas Quellcodeklasse MyThread erweitert Thread {public myThread (String name) {Super (name); } public void run () {System.out.println (Thread.currentThread (). getName ()+"läuft"); }}; public class Demo {public static void main (String [] args) {Thread mythead = new MyThread ("myThread"); System.out.println (Thread.currentThread (). GetName ()+"rufen Sie Mythead.run ()"); MyThread.run (); System.out.println (Thread.currentThread (). GetName ()+"rufen Sie Mythead.start ()"); mythead.start (); }} Auslaufergebnisse:
Hauptaufruf mythead.run () Hauptstufe RunningMain Call Mythead.Start () MyThread läuft
Ergebnisse Beschreibung:
(1) Thread.CurrentThread (). GetName () wird verwendet, um den Namen "aktueller Thread" zu erhalten. Der aktuelle Thread bezieht sich auf den Thread, der in der CPU ausgeführt werden soll.
(2) mythead.run () wird in "Haupt -Thread Main" bezeichnet, und die Run () -Methode wird direkt auf "Hauptfaden Haupt" ausgeführt.
(3) MyThread.Start () startet "Thread MyThread". Nachdem "Thread MyThread" gestartet wurde, wird die Run () -Methode aufgerufen; Zu diesem Zeitpunkt wird die Run () -Methode auf "Thread MyThread" ausgeführt.
Thread -Interrupts und -terminationen
1. Thread Interrupt: Interrupt ()
Die Funktion von Interrupt () besteht darin, den Thread zu unterbrechen.
Dieser Thread darf sich selbst unterbrechen; Wenn andere Threads die Interrupt () -Methode dieses Threads aufrufen, wird die Berechtigung über checkAccess () überprüft. Dies kann eine SecurityException -Ausnahme ausführen.
Wenn sich der Thread in einem Blockierstatus befindet: Wait (), Warten Sie (lang) oder warten (lang, int) des Threads wird es in einen Warten (Blockierstatus) oder ein Anruf Join (), Join (lang), Join (lang, int), Schlaf (lang), Schlaf (lang, int) des Threads in einen Blockierungszustand. Wenn der Thread seine Interrupt () -Methode aufruft, wenn er blockiert, wird sein "Interrupt -Zustand" gelöscht und eine InterruptedException empfangen. Beispielsweise tritt ein Thread durch Wait () in einen Blockierungszustand ein, und der Thread wird durch Interrupt () unterbrochen. Das Aufrufen von Interrupt () setzt die Interrupt -Flagge des Threads sofort auf "True", aber da sich der Thread in einem Blockierungszustand befindet, wird die "Interrupt -Flagge" sofort auf "false" gelöscht, und eine InterruptedException wird generiert.
Wenn der Faden in einem Selektor -Selektor blockiert ist, dann wird er durch Interrupt () unterbrochen. Das Interrupt -Flag des Threads ist auf True eingestellt und wird sofort aus dem Auswahlvorgang zurückgegeben.
Wenn es nicht zur oben genannten Situation gehört, wird das Interrupt -Flag, wenn der Thread durch Interrupt () unterbrochen wird, auf "wahr" gesetzt.
Durch die Unterbrechung eines "beendeten Threads" wird keine Operation verursacht.
2. Fadenabschluss
Die Stop ()- und suspend () -Methoden im Thread werden aufgrund ihrer inhärenten Unsicherheit nicht verwendet!
Als nächstes werde ich zunächst die Beendungsmethode von Threads in "Blocking State" bzw. "Laufstatus" diskutieren und dann eine allgemeine Methode zusammenfassen.
1. Beenden Sie den Faden im "Blockierungszustand"
Normalerweise beenden wir einen Faden in einem "Blockierungszustand", indem wir "unterbrechen".
Wenn der Faden in einen Blockierungszustand eingeht, weil er als Schlaf (), Wait (), Join () und andere Methoden bezeichnet wird; Wenn der Interrupt () des Threads zu diesem Zeitpunkt aufgerufen wird, wird die Interrupt -Marke des Threads auf true eingestellt. Da es sich in einem Blockierungszustand befindet, wird die Interrupt -Flagge gelöscht und eine InterruptedException -Ausnahme erzeugt. Wenn Sie die InterruptedException einstellen, bis er angemessen ist, kann der Thread in der Form wie folgt terminieren:
@Overridepublic void run () {try {while (true) {// Die Aufgabe ausführen ...}} catch (interruptedException ie) {// Aufgrund einer InterruptedException -Ausnahme, beenden Sie die while (true) Schleife und die Thread -Kündigungen! }} HINWEIS: Wenn die Aufgabe kontinuierlich ausgeführt wird (True), erzeugt der Aufruf an Interrupt () des Threads einen InterruptedException -Interrupt. Die unterbrochene Erfassung ist draußen, während (wahr) draußen (wahr) und damit die while (wahre) Schleife verlässt!
Hinweis: Die Erfassung von InterruptedException wird normalerweise außerhalb des (wahren) Schleifenkörpers platziert, so dass die while (wahre) Schleife beim Erstellen einer Ausnahme ausgeht. Andernfalls ist eine zusätzliche Zusatz- und Ausgangsverarbeitung erforderlich, wenn die InterruptedException innerhalb des (wahren) Schleifungskörpers liegt. Die Form ist wie folgt:
@Overridepublic void run () {while (true) {try {// Task ausführen ...} catch (InterruptedException dh) {// InterruptedException ist in der while (true) Schleifenkörper. // Wenn der Thread eine InterruptedException -Ausnahme erzeugt, kann (wahr) weiter laufen! Müssen die Pause manuell beenden; }}} HINWEIS: Die obige InterruptedException -Ausnahme ist in WHLE (True) gefangen. Wenn eine InterruptedException -Ausnahme erzeugt wird, wird sie nicht durch Fang behandelt und befindet sich noch im (wahren) Schleifenkörper; Um den (wahren) Schleifenkörper zu beenden, muss eine zusätzliche Operation des Ausgangs der while (true) durchgeführt werden.
2. Beenden Sie den Thread in "Laufstatus"
Normalerweise beenden wir einen Thread in einem "Laufstatus", indem wir "markieren". Unter ihnen enthält es "Interrupt Flag" und "zusätzliche Flagge hinzufügen".
(1) Beenden Sie den Faden durch "Interrupt Flag".
Die Form ist wie folgt:
@Overridepublic void run () {while (! IsInterrupted ()) {// Task ausführen ...}} Beschreibung: Isinterrupted () bestimmt, ob das Interrupt -Flag des Threads wahr ist. Wenn der Thread im Laufstatus ist und wir ihn beenden; Die Interrupt () -Methode des Threads kann aufgerufen werden, und das Interrupt -Flag des Threads ist wahr, das heißt, stellt () wahr. Zu diesem Zeitpunkt wird die während der Schleife beendet.
Hinweis: Interrupt () beendet Threads in "Running Status" nicht! Es setzt die Interrupt -Flagge des Threads auf True.
(2) Pass "Zusätzliche Markierungen hinzufügen".
Die Form ist wie folgt:
Private volatile boolean Flag = true; protected void stoptask () {flag = false;}@oversidepublic void run () {while (flag) {// Task ausführen ...}} Beschreibung: Im Thread befindet sich ein Flag -Tag, und sein Standardwert ist wahr. und wir stellen stoptask () an, um das Flag -Tag festzulegen. Wenn wir den Thread enden müssen, kann das Aufrufen der Stoptask () -Methode des Threads den Thread die while Schleife beenden.
HINWEIS: Das Flag ist definiert als der flüchtige Typ, um die Sichtbarkeit des Flags zu gewährleisten. Nachdem andere Threads das Flag über Stoptask () geändert haben, kann dieser Thread den geänderten Flag -Wert sehen.
Umfassende Beendigmethoden von Threads in "Blocking State" und "Running State" sind die häufigeren Beendigungsthreads wie folgt:
@OverridePublic void run () {try {// 1. isinterrupted () garantiert, dass der Thread beendet wird, solange der Interrupt true markiert ist. while (! is interrupted ()) {// Task ausführen ...}} catch (InterruptedException dh) {// 2. InterruptedException -Ausnahme garantiert, dass der Thread beendet wird, wenn eine InterruptedException -Ausnahme auftritt. }} 3. Beispiel für den Abschluss von Thread
Interrupt () wird häufig verwendet, um einen "Blockierungszustand" -Faden zu beenden. Siehe das folgende Beispiel:
// Demo1.javas Quellcodeklasse MyThread erweitert Thread {public myThread (String name) {Super (name); } @Override public void run () {try {int i = 0; while (! ist interrupted ()) {Thread.sleep (100); // Schlaf 100 ms i ++; System.out.println (Thread.currentThread (). GetName ()+"("+this.getState ()+") Schleife"+i); }} catch (InterruptedException e) {System.out.println (Thread.currentThread (). getName ()+"("+this.getState ()+") catch InterruptedException."); }}} public class Demo1 {public static void main (String [] args) {try {thread t1 = new MyThread ("t1"); // Erstellen Sie einen neuen "Thread T1" system.out.println (t1.getName ()+"("+t1.getState ()+") ist neu."); t1.start (); // Start "Thread t1" system.out.println (t1.getName ()+"("+t1.getState ()+") wird gestartet."); // Der Hauptfaden schläft für 300 ms, und dann sendet der Hauptfaden eine "Interrupt" -Berätigung an T1. Thread.Sleep (300); t1.interrupt (); System.out.println (t1.getName ()+"("+t1.getState ()+") wird unterbrochen."); // Der Hauptfaden schläft für 300 ms und überprüft dann den Status von T1. Thread.Sleep (300); System.out.println (t1.getName ()+"("+t1.getState ()+") wird jetzt unterbrochen."); } catch (interruptedException e) {e.printstacktrace (); }}} Auslaufergebnisse:
T1 (neu) ist neu. T1 (Runnable) wird gestartet.
Ergebnisse Beschreibung:
(1) Das Hauptfaden -Haupthaupt erzeugt Thread T1 über New MyThread ("T1") und startet dann T1 bis T1.Start ().
(2) Nach dem Start von T1 wird seine Interrupt -Flagge kontinuierlich überprüft. Wenn die Interrupt -Flagge "falsch" ist, schläft sie 100 ms.
(3) Nach dem Schlafengehen von T1 wechselt es zur Hauptfaden -Haupthaupt. Wenn der Hauptfaden erneut ausgeführt wird, wird t1.interrupt () ausgeführt, um Thread T1 zu unterbrechen. Nachdem T1 die Interrupt -Anweisung erhalten hat, wird die Interrupt -Flag von T1 auf "False" gesetzt und eine InterruptedException wird geworfen. In der Run () -Methode von T1 ist es eine Ausnahme, die während des Schleifenkörpers gefangen ist; Daher wird die Schleife beendet.
Wir haben eine kleine Änderung des obigen Ergebnisses vorgenommen und den Codeblock verlegt, der die InterruptedException -Ausnahme in der Run () -Methode auf den while -Loop -Körper erhielt.
// Demo2.javas Quellcodeklasse MyThread erweitert Thread {public myThread (String name) {Super (name); } @Override public void run () {int i = 0; while (! ist interrupted ()) {try {thread.sleep (100); // Schlaf für 100 ms} catch (InterruptedException IE) {System.out.println (Thread.CurrentThread (). GetName ()+"("+this.getState ()+") catch InterruptedException."); } i ++; System.out.println (Thread.currentThread (). GetName ()+"("+this.getState ()+") Schleife"+i); }}} public class Demo2 {public static void main (String [] args) {try {thread t1 = new MyThread ("t1"); // Erstellen Sie einen neuen "Thread T1" system.out.println (t1.getName ()+"("+t1.getState ()+") ist neu."); t1.start (); // Start "Thread t1" system.out.println (t1.getName ()+"("+t1.getState ()+") wird gestartet."); // Der Hauptfaden schläft für 300 ms, und dann sendet der Hauptfaden eine "Interrupt" -Berätigung an T1. Thread.Sleep (300); t1.interrupt (); System.out.println (t1.getName ()+"("+t1.getState ()+") wird unterbrochen."); // Der Hauptfaden schläft für 300 ms und überprüft dann den Status von T1. Thread.Sleep (300); System.out.println (t1.getName ()+"("+t1.getState ()+") wird jetzt unterbrochen."); } catch (interruptedException e) {e.printstacktrace (); }}} Auslaufergebnisse:
T1 (neu) ist neu. T1 (Runnable) wird gestartet. (Runnable) Loop 6T1 (Runnable) Loop 7T1 (Runnable) Loop 8T1 (Runnable) Loop 9 ...
Ergebnisse Beschreibung:
Das Programm ist in eine tote Schleife eingetreten!
Warum passiert das? Dies liegt daran, dass T1 durch Interrupt () unterbrochen wird, wenn es "auf (Blockierung) des Zustands wartet". Zu diesem Zeitpunkt wird die Interrupt -Flagge gelöscht [die unterbrochen () falsch zurückgibt], und eine InterruptedException -Ausnahme wird ausgelöst [diese Ausnahme wird in den WHE -Schleifenkörper gefangen]. Daher wird T1 natürlich in einen Teufelskreis eintreten.
Um dieses Problem zu lösen, müssen wir zusätzliche Verarbeitung bearbeiten, um die While -Schleife zu beenden, wenn Sie die Ausnahme erwischen. Beispielsweise kann das Hinzufügen von Pausen oder Rückkehr zu MyThread Catch (InterruptedException) das Problem lösen.
Hier ist ein Beispiel für einen Thread, der einen "Statuszustand" beendet, indem "zusätzliche Tags hinzugefügt" werden:
// Demo3.javas Quellcodeklasse MyThread erweitert Thread {private volatile boolean Flag = true; public void stoptask () {flag = false; } public myThread (String -Name) {Super (Name); } @Override public void run () {synchronized (this) {try {int i = 0; while (flag) {thread.sleep (100); // Schlaf 100 ms i ++; System.out.println (Thread.currentThread (). GetName ()+"("+this.getState ()+") Schleife"+i); }} catch (InterruptedException IE) {System.out.println (thread.currentThread (). getName ()+"("+this.getState ()+") catch InterruptedException."); }}}} public class Demo3 {public static void main (String [] args) {try {myThread t1 = new MyThread ("t1"); // Erstellen Sie einen neuen "Thread T1" system.out.println (t1.getName ())+"("+t1.getState ()+") ist neu."); t1.start (); // Start "Thread t1" system.out.println (t1.getName ()+"("+t1.getState ()+") wird gestartet."); // Der Hauptfaden schläft für 300 ms, und dann sendet der Hauptfaden eine "Interrupt" -Berätigung an T1. Thread.Sleep (300); t1.Stoptask (); System.out.println (t1.getName ()+"("+t1.getState ()+") wird unterbrochen."); // Der Hauptfaden schläft für 300 ms und überprüft dann den Status von T1. Thread.Sleep (300); System.out.println (t1.getName ()+"("+t1.getState ()+") wird jetzt unterbrochen."); } catch (interruptedException e) {e.printstacktrace (); }}} Auslaufergebnisse:
T1 (neu) ist neu. T1 (Runnable) wird gestartet.