Multi-Threading in Java erfolgt durch Definition von run () und Aufruf von start ().
Starten Sie Delegaten zu einer systemeigenen Methode, die einen Thread durch Betriebssystemroutinen startet, und run () wird innerhalb dieses neu erstellten Threads aufgerufen.
Wenn eine eigenständige Anwendung gestartet wird, wird automatisch ein Haupt-Thread erstellt, um main () auszuführen.
Betrachte diesen Code -
%Vor%Dies ist die Ausgabe -
%Vor%Wenn main () -Methode über einen Thread gestartet wird, wird run () nicht am Anfang der Aufrufhierarchie angezeigt?
Wie kann der Haupt-Thread erzeugt werden, ohne Runnable zu implementieren?
Ich habe mir die Interna der JVM nicht angesehen, aber ich würde vermuten, dass die JVM den Hauptthread instanziiert, um die Hauptmethode auszuführen, aber diesen Hauptthread direkt durch Aufruf von nativem Code ausführt, ohne die klassischen Java-Klassen zu durchlaufen und Methoden, um den Thread zu starten.
Wenn main () -Methode über einen Thread gestartet wird, wird run () nicht am Anfang der Aufrufhierarchie angezeigt?
Wie andere bereits erwähnt haben, liegt das daran, dass der "Haupt" -Thread speziell ist. Es wird nicht über die standardmäßigen Thread
-Klassenmechanismen gestartet, sondern über Java-Bootstrap-Code. Der public static void main(String[] args)
wird immer vom Hauptthread aus systemeigenem Code ausgeführt.
Eine andere Erklärung ist, dass es tatsächlich eine run()
-Methode gibt, aber die Art, wie sie den Stack-Frame aufbauen, versteckt sie absichtlich, um den Benutzer nicht zu verwirren. Zum Beispiel, da Sie eine new Thread(new Test())
machen, dann ist Ihre Test
-Klasse tatsächlich das target
-Feld innerhalb der Thread
. Wenn der Hintergrund Thread
gestartet wird, ruft er tatsächlich Thread.run()
auf, das den Code hat:
Aber wir sehen nie die Methode Thread.run()
im Stackframe, obwohl es so aussieht, als müsste sie da sein. Die run()
Methode wäre im Stackframe, wenn der Benutzer sie in einer Thread
Superklasse überschreiben würde. Es könnte vom JDK entfernt werden, um die Stackframe-Ausgabe zu verbessern.
Multi-Threading in Java wird durch das Definieren von run () und das Aufrufen von start () durchgeführt.
Das stimmt, aber für die Nachwelt hielt ich es für wichtig zu erkennen, dass Ihr Code ein Problem hat. Ihre Test
Klasse sollte nicht Thread
erweitern, sondern stattdessen Runnable
implementieren. Es funktioniert, weil Thread
implementiert Runnable
.
Entweder sollten Sie Runnable
implementieren und Ihren Code so ändern:
Oder Sie erweitern Thread
und ändern die Art, wie Sie Ihren Thread starten, in etwa wie folgt. Das obige Runnable
-Muster wird empfohlen, da es Ihrem Test
-Thread ermöglicht, bei Bedarf eine andere Klasse zu erweitern.
Warum ist das wichtig? Ihr aktueller Code instanziiert tatsächlich 2 Thread
-Objekte, aber nur einer davon ist start()
ed und läuft als Hintergrund Thread
. Sie könnten etwas wie den folgenden Fehler haben:
main-Methode wird in einem separaten Thread von JVM gestartet, es ist der übergeordnete Thread des untergeordneten Threads, deshalb sehen Sie untergeordneten Thread nicht an der Spitze der Aufrufhierarchie.
Also in Ihrem Fall hat JVM einen Thread erstellt, der Ihr Programm gestartet hat, was auch Thread erweitert.
Dann haben Sie in Ihrer Hauptmethode eine neue Instanz Ihrer Klasse namens "start" erstellt, die einen neuen Thread startet, der von der JVM gestartet wird, um Ihr Programm zu starten.
Da die main-Methode ein Ausgangspunkt für ein eigenständiges Java-Programm ist, liegt es in der Verantwortung von JVM, sie in einem separaten Thread zu starten, für den Sie keinen Code schreiben.
Beim Starten eines Programms durch Aufruf der main-Methode benötigt JVM keinen Thread oder keine ausführbare Runnable, sondern eine Standardprozedur.
Beschreibung von Inside Java Virtual Machine
Die Methode main () der anfänglichen Klasse einer Anwendung dient als Ausgangspunkt für den ersten Thread dieser Anwendung. Die Initiale Thread kann wiederum andere Threads auslösen.
Innerhalb der Java Virtual Machine gibt es Threads in zwei Varianten: Daemon und Nicht-Daemon. Ein Daemon-Thread ist normalerweise ein Thread, der von der virtuelle Maschine selbst, wie ein Thread, der Müll ausführt Sammlung. Die Anwendung kann jedoch alle von ihr erstellten Threads markieren als Daemon-Threads. Der erste Thread einer Anwendung - der eine Beginnt bei main () - ist ein Nicht-Daemon-Thread.
Eine Java-Anwendung wird weiterhin ausgeführt (die VM-Instanz) läuft weiter) solange alle Nicht-Daemon-Threads still sind Laufen. Wenn alle Nicht-Daemon-Threads einer Java-Anwendung beendet werden, Die Instanz der virtuellen Maschine wird beendet. Wenn von der Sicherheit erlaubt Manager kann die Anwendung auch ihren eigenen Untergang verursachen, indem sie die exit () Methode der Klasse Runtime oder System.
Die Aufrufhierarchie wird nicht von Ihnen geregelt, sie unterliegt dem zugrunde liegenden Thread-Scheduler.
Also zum Beispiel Wenn ich den gleichen Code auf meinem Rechner laufen lasse, ist dies die Ausgabe
%Vor%Wenn Sie also Ihr Beispiel ausgeführt haben, wählen Sie im Scheduler, dass der untergeordnete Thread zuerst vor main gehen soll.
Hinzufügen zu @JB Nizet, wie ein Programm aufgerufen wird oder wie ein Thread-Lebenszyklus implementiert wird, hängt vom zugrundeliegenden Betriebssystem und der Hardware ab, was variieren wird.
Keine einzelne Implementierungsdetails würde eine vollständige Antwort liefern, jede Implementierung wird variieren.
Vielleicht ist es ein semantisches Argument, aber ein Thread und ein Prozess sind auch nicht.
Ein Prozess wird vom Betriebssystem gestartet und verfügt über eigene private Codepages (kompilierter Code). Ein Thread wird von den internen Komponenten des Programms gestartet und gibt zunächst die Codepages seines übergeordneten Elements (kompilierter Code) frei.
Dass die JVM intern einen Thread zum Ausführen der Hauptmethode verwendet, ist ein Implementierungsdetail der Umgebung, aber keine Repräsentation der Java-Sprache. Wenn ein Thread in den main
Stack-Frames gemeldet werden sollte, wäre die Architektur der Rückverweisung auf die Quellcode-Position unmöglich, da dieser Main-Serving-Thread keine Kompilierungseinheit hätte (er ist intern in der JVM).
Tags und Links java multithreading