CodeGym /Java-Blog /Random-DE /Multithreading: Was die Methoden der Thread-Klasse bewirk...
Autor
Pavlo Plynko
Java Developer at CodeGym

Multithreading: Was die Methoden der Thread-Klasse bewirken

Veröffentlicht in der Gruppe Random-DE
Hallo! Heute sprechen wir weiter über Multithreading. Sehen wir uns die Thread-Klasse und die Funktionsweise einiger ihrer Methoden an. Wenn wir früher Klassenmethoden untersucht haben, haben wir normalerweise einfach Folgendes geschrieben: <Methodenname> -> <was die Methode tut>. Multithreading: Was die Methoden der Thread-Klasse bewirken - 1Mit den Methoden von wird das nicht funktionieren Thread:) Sie verfügen über eine komplexere Logik, die Sie ohne ein paar Beispiele nicht verstehen können.

Die Thread.start()-Methode

Beginnen wir damit, uns zu wiederholen. Wie Sie sich wahrscheinlich erinnern, können Sie einen Thread erstellen, indem Sie Ihre Klasse veranlassen, die ThreadKlasse zu erben und die run()Methode zu überschreiben. Aber es startet natürlich nicht von selbst. Dazu rufen wir start()die Methode unseres Objekts auf. Multithreading: Was die Methoden der Thread-Klasse bewirken - 2Erinnern wir uns an das Beispiel aus der vorherigen Lektion:

public class MyFirstThread extends Thread {

   @Override
   public void run() {
       System.out.println("Thread executed: " + getName());
   }
}


public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.start();
       }
   }
}
Hinweis:start() Um einen Thread zu starten, müssen Sie die spezielle Methode und nicht dierun()MethodeaufrufenDies ist ein leicht zu begehender Fehler, insbesondere wenn Sie sich zum ersten Mal mit Multithreading beschäftigen. Wenn Sie in unserem Beispiel dierun()Methode zehnmal anstelle vonstart(), erhalten Sie Folgendes:

public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.run();
       }
   }
}
Sehen Sie sich die Ergebnisse unseres Programms an: Thread ausgeführt: Thread-0 Thread ausgeführt: Thread-1 Thread ausgeführt: Thread-2 Thread ausgeführt: Thread-3 Thread ausgeführt: Thread-4 Thread ausgeführt: Thread-5 Thread ausgeführt: Thread-6 Thread ausgeführt: Thread-7 Thread ausgeführt: Thread-8 Thread ausgeführt: Thread-9 Schauen Sie sich die Reihenfolge der Ausgabe an: Alles geschieht in perfekter Reihenfolge. Seltsam, oder? Wir sind daran nicht gewöhnt, weil wir bereits wissen, dass die Reihenfolge, in der Threads gestartet und ausgeführt werden, von einem übergeordneten Intellekt in unserem Betriebssystem bestimmt wird: dem Thread-Scheduler. Vielleicht hatten wir einfach Glück? Dabei geht es natürlich nicht um Glück. Sie können dies überprüfen, indem Sie das Programm noch einige Male ausführen. Das Problem ist, dass der Anruf erfolgtrun()Methode hat direkt nichts mit Multithreading zu tun. In diesem Fall wird das Programm im Hauptthread ausgeführt, dem gleichen Thread, der die main()Methode ausführt. Es werden einfach nacheinander 10 Zeilen auf der Konsole ausgegeben und fertig. 10 Threads wurden nicht gestartet. Denken Sie also in Zukunft daran und überprüfen Sie sich ständig. Wenn Sie möchten, dass die run()Methode aufgerufen wird, rufen Sie auf start(). Gehen wir weiter.

Die Thread.sleep()-Methode

Um die Ausführung des aktuellen Threads für eine Weile anzuhalten, verwenden wir die sleep()Methode. Multithreading: Was die Methoden der Thread-Klasse bewirken - 3Die sleep()Methode benötigt eine Anzahl von Millisekunden als Argument, die angibt, wie lange es dauert, den Thread in den Ruhezustand zu versetzen.

public class Main {

   public static void main(String[] args) throws InterruptedException {

       long start = System.currentTimeMillis();

       Thread.sleep(3000);

       System.out.println(" - How long did I sleep? \n - " + ((System.currentTimeMillis()-start)) / 1000 + " seconds");

   }
}
Konsolenausgabe: - Wie lange habe ich geschlafen? - 3 Sekunden Hinweis: Die sleep()Methode ist statisch: Sie schläft den aktuellen Thread. Das heißt, derjenige, der gerade ausgeführt wird. Hier noch ein wichtiger Punkt: Ein schlafender Thread kann unterbrochen werden. In diesem Fall wirft das Programm eine InterruptedException. Nachfolgend betrachten wir ein Beispiel. Was passiert übrigens, nachdem der Thread aufgewacht ist? Wird die Ausführung dort fortgesetzt, wo sie aufgehört hat? Nein. Nachdem ein Thread aufgewacht ist, dh die als Argument übergebene Zeit abgelaufen ist Thread.sleep(), geht er in den ausführbaren Zustand überZustand. Dies bedeutet jedoch nicht, dass der Thread-Scheduler es ausführt. Möglicherweise gibt es einem anderen nicht schlafenden Thread den Vorzug und ermöglicht unserem frisch erwachten Thread, seine Arbeit etwas später fortzusetzen. Denken Sie unbedingt daran: Aufwachen bedeutet nicht, sofort mit der Arbeit fortzufahren!

Die Thread.join()-Methode

Multithreading: Was die Methoden der Thread-Klasse bewirken - 4Die join()Methode unterbricht die Ausführung des aktuellen Threads, bis ein anderer Thread beendet ist. Wenn wir 2 Threads haben t1und t2und wir schreiben

t1.join()
t2startet dann erst, wenn t1seine Arbeit beendet ist. Die join()Methode kann verwendet werden, um die Ausführungsreihenfolge von Threads zu garantieren. Betrachten wir die join()Funktionsweise der Methode im folgenden Beispiel:

public class ThreadExample extends Thread {

   @Override
   public void run() {

       System.out.println("Thread started: " + getName());

       try {
           Thread.sleep(5000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println("Thread " + getName() + " is finished.");
   }
}


public class Main {

   public static void main(String[] args) throws InterruptedException {

       ThreadExample t1 = new ThreadExample();
       ThreadExample t2 = new ThreadExample();

       t1.start();


 /* The second thread (t2) will start running only after the first thread (t1)
       is finished (or an exception is thrown) */
       try {
           t1.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       t2.start();

       // The main thread will continue running only after t1 and t2 have finished
       try {
           t1.join();
           t2.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       System.out.println("All threads have finished. The program is finished.");

   }
}
Wir haben eine einfache ThreadExampleKlasse erstellt. Seine Aufgabe besteht darin, eine Meldung anzuzeigen, dass der Thread gestartet wurde, 5 Sekunden lang einzuschlafen und schließlich zu melden, dass die Arbeit abgeschlossen ist. Stück Kuchen. Die Hauptlogik liegt in der MainKlasse. Schauen Sie sich die Kommentare an: Wir verwenden die join()Methode, um die Ausführungsreihenfolge der Threads erfolgreich zu verwalten. Wenn Sie sich erinnern, wie wir mit diesem Thema begonnen haben, wird die Ausführungsreihenfolge vom Thread-Scheduler verwaltet. Es führt Threads nach eigenem Ermessen aus: jedes Mal auf eine andere Art und Weise. Hier verwenden wir die Methode, um sicherzustellen, dass t1zuerst der Thread gestartet und ausgeführt wird, dann dert2Thread, und erst danach wird der Hauptthread des Programms fortgesetzt. Weiter geht's. In realen Programmen kommt es oft vor, dass Sie die Ausführung eines Threads unterbrechen müssen. Beispielsweise läuft unser Thread, wartet aber auf ein bestimmtes Ereignis oder eine bestimmte Bedingung. Wenn es auftritt, stoppt der Thread. Es wäre wahrscheinlich sinnvoll, wenn es eine stop()Methode gäbe. Aber es ist nicht so einfach. Es war einmal, dass Java tatsächlich eine Thread.stop()Methode hatte und die Unterbrechung eines Threads ermöglichte. Später wurde es jedoch aus der Java-Bibliothek entfernt. Sie können es in der Oracle-Dokumentation finden und sehen, dass es als veraltet markiert ist. Warum? Weil es den Thread einfach gestoppt hat, ohne etwas anderes zu tun. Beispielsweise könnte der Thread mit Daten arbeiten und etwas ändern. Dann wurde es mitten in seiner Arbeit abrupt und kurzerhand durch die stop()Methode abgebrochen. Ohne ordnungsgemäßes Herunterfahren, ohne die Freigabe von Ressourcen, ohne Fehlerbehandlung – all das gab es nicht. Um es leicht zu übertreiben: Die stop()Methode zerstörte einfach alles, was ihr in den Weg kam. Es war, als würde man das Netzkabel aus der Steckdose ziehen, um den Computer auszuschalten. Ja, Sie können das gewünschte Ergebnis erzielen. Aber jeder weiß, dass der Computer es Ihnen nach ein paar Wochen nicht mehr danken wird, dass Sie ihn so behandeln. Aus diesem Grund hat sich in Java die Logik zum Unterbrechen von Threads geändert und verwendet nun eine spezielle interrupt()Methode.

Die Thread.interrupt()-Methode

Was passiert, wenn die interrupt()Methode in einem Thread aufgerufen wird? Es gibt 2 Möglichkeiten:
  1. joinWenn sich das Objekt beispielsweise aufgrund der oder- Methoden im Wartezustand befand sleep, wird das Warten unterbrochen und das Programm löst eine aus InterruptedException.
  2. Wenn sich der Thread in einem funktionierenden Zustand befand, interruptedwird das boolesche Flag für das Objekt gesetzt.
Aber wir müssen den Wert dieser Flagge am Objekt überprüfen und die Arbeit selbst korrekt abschließen! Deshalb Threadhat die Klasse die boolean isInterrupted()Methode. Kehren wir zum Uhrenbeispiel aus einer Lektion im Grundkurs zurück. Der Einfachheit halber haben wir es etwas vereinfacht:

public class Clock extends Thread {

   public static void main(String[] args) throws InterruptedException {
       Clock clock = new Clock();
       clock.start();

       Thread.sleep(10000);
       clock.interrupt();
   }

   public void run() {
       Thread current = Thread.currentThread();

       while (!current.isInterrupted())
       {
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               System.out.println("The thread was interrupted");
               break;
           }
           System.out.println("Tick");
       }
   }
}
In diesem Fall wird die Uhr gestartet und beginnt im Sekundentakt zu ticken. In der 10. Sekunde unterbrechen wir den Takt der Uhr. Wie Sie bereits wissen, ist das Ergebnis ein , wenn sich der Thread, den wir zu unterbrechen versuchen, in einem der Wartezustände befindet InterruptedException. Dies ist eine geprüfte Ausnahme, sodass wir sie leicht abfangen und unsere Logik ausführen können, um das Programm zu beenden. Und genau das haben wir getan. Hier ist unser Ergebnis: Tick Tick Tick Tcik Tick Tick Tick Tick Tick Der Thread wurde unterbrochen. Damit ist unsere Einführung in die Threadwichtigsten Methoden der Klasse abgeschlossen. Viel Glück!
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION