Sprechen wir zunächst über das konzeptionelle Wissen in Bezug auf Anwendungen und Prozesse in Java und erklären Sie dann, wie Sie Threads erstellen und wie man Prozesse erstellt. Hier ist der Verzeichnisriss dieses Artikels:
1. Konzepte im Zusammenhang mit Anwendungen und Prozessen in Java
2. So erstellen Sie Threads in Java
3.Wie, um einen Prozess in Java zu erstellen
1. Konzepte im Zusammenhang mit Anwendungen und Prozessen in Java
In Java entspricht eine Anwendung einer JVM -Instanz (auch als JVM -Prozess bezeichnet) und der Name standardmäßig java.exe oder javaw.exe (kann über den Task -Manager unter Windows angezeigt werden). Java nimmt ein Programmiermodell mit einem Thread an, dh wenn wir nicht aktiv Threads in unserem eigenen Programm erstellen, erstellen wir nur einen Thread, der normalerweise als Hauptfaden bezeichnet wird. Seien Sie sich jedoch bewusst, dass es zwar nur einen Thread gibt, der Aufgaben ausführt, bedeutet nicht, dass es nur einen Thread im JVM gibt. Beim Erstellen einer JVM -Instanz werden viele andere Threads erstellt (z. B. Müllsammlungsfäden).
Da Java ein Programmiermodell mit einem Thread-Programm annimmt, sollten Sie beim Programmieren der Benutzeroberfläche zeitaufwändige Vorgänge in den untergeordneten Thread einstellen, um zu vermeiden, dass der Haupt-Thread blockiert wird (beim Programmieren der Benutzeroberfläche ist der Haupt-Thread der UI-Thread, der zur Verarbeitung von Benutzer-Interaktionsereignissen verwendet wird).
2. So erstellen Sie Threads in Java
Wenn Sie einen Thread in Java erstellen möchten, gibt es im Allgemeinen zwei Möglichkeiten: 1) Erben Sie die Thread -Klasse; 2) Implementieren Sie die Runnable -Schnittstelle.
1. Erben Sie die Thread -Klasse
Wenn Sie die Thread -Klasse erben, müssen Sie die Auslaufmethode überschreiben und die Aufgaben definieren, die in der Run -Methode ausgeführt werden müssen.
Klasse myThread erweitert Thread {private static int num = 0; public myThread () {num ++; } @Override public void run () {System.out.println ("aktiv erstellt"+num+"threads"); }}Nachdem Sie Ihre eigene Thread -Klasse erstellt haben, können Sie ein Thread -Objekt erstellen und den Thread über die Start () -Methode starten. Beachten Sie, dass es nicht als Run () -Methode bezeichnet wird, um den Thread zu starten. Die Run -Methode definiert nur die Aufgaben, die ausgeführt werden müssen. Wenn die Run -Methode aufgerufen wird, entspricht sie der Ausführung der Run -Methode im Haupt -Thread, was sich nicht von normalen Methodenaufrufen unterscheidet. Zu diesem Zeitpunkt wird kein neuer Thread erstellt, um die definierten Aufgaben auszuführen.
public class test {public static void main (String [] args) {MyThread thread = new mythead (); Thread.Start (); }} Klasse MyThread erweitert Thread {private statische int num = 0; public myThread () {num ++; } @Override public void run () {System.out.println ("aktiv erstellt"+num+"threads"); }}Im obigen Code wird durch Aufrufen der Start () -Methode ein neuer Thread erstellt. Um den Unterschied zwischen Start () -Methodenaufrufen und Run () -Methodenaufrufen zu unterscheiden, finden Sie im folgenden Beispiel:
public class test {public static void main (String [] args) {System.out.println ("Haupt -Thread -ID:"+thread.currentThread (). getId ()); Mythead thread1 = new MyThread ("Thread1"); Thread1.Start (); Mythead thread2 = new MyThread ("Thread2"); thread2.run (); }} class myThread erweitert Thread {private String -Name; public myThread (String name) {this.name = name; } @Override public void run () {system.out.println ("name:"+name+"untergeordnete Thread -ID:"+thread.currentThread (). GetId ()); }}Auslaufergebnisse:
Aus den Ausgabeergebnissen können die folgenden Schlussfolgerungen gezogen werden:
1) Die Thread -IDs von Thread1 und Thread2 sind unterschiedlich, und Thread2 und die Haupt -Thread -ID sind gleich. Dies bedeutet, dass der Run -Methode -Aufruf keinen neuen Thread erstellt, sondern die Auslaufmethode im Haupt -Thread direkt ausführt, was nicht von normalen Methodenaufrufen unterschiedlich ist.
2) Obwohl der Thread1 -Aufruf der Startmethode 1 vor der Auslaufmethode von Thread2 aufgerufen wird, wird zuerst die Informationen zum Ausgangsmethode von Thread2 ausgegeben, was darauf hinweist, dass der Prozess des Erstellens eines neuen Threads die nachfolgende Ausführung des Haupt -Threads nicht blockiert.
2. Implementieren Sie die Runnable -Schnittstelle
Zusätzlich zum Erben der Thread -Klasse kann das Erstellen von Threads in Java auch ähnliche Funktionen implementieren, indem die Runnable -Schnittstelle implementiert wird. Das Implementieren der Runnable -Schnittstelle muss die Auslaufmethode überschreiben.
Hier ist ein Beispiel:
public class test {public static void main (String [] args) {System.out.println ("Haupt -Thread -ID:"+thread.currentThread (). getId ()); Myrunnable runnable = new Myrunnable (); Thread Thread = neuer Thread (runnable); Thread.Start (); }} class Myrunnable implements runnable {public myrunnable () {} @Override public void run () {System.out.println ("Subhread ID:"+thread.currentThread (). getId ()); }}Runnable bedeutet "Aufgabe" auf Chinesisch. Wie der Name schon sagt, definieren wir durch die Implementierung der Runnable -Schnittstelle eine Subtask und übergeben dann die Subtask zum Ausführen zu Thread. Beachten Sie, dass diese Methode Runnable als Parameter für die Thread -Klasse verwenden muss, und dann einen neuen Thread erstellen, um die Subtask über die Thread -Startmethode auszuführen. Wenn die Runnable -Methode aufgerufen wird, wird kein neuer Thread erstellt, und es gibt keinen Unterschied zwischen diesem normalen Methodenaufruf.
Wenn Sie sich den Implementierungsquellcode der Thread -Klasse ansehen, werden Sie feststellen, dass die Thread -Klasse die Runnable -Schnittstelle implementiert.
In Java können diese beiden Methoden verwendet werden, um Threads zum Ausführen von Unteraufgaben zu erstellen. Die spezifische Auswahlmethode hängt von Ihren Anforderungen ab. Wenn Sie die Thread -Klasse direkt erben, sieht sie möglicherweise prägnanter aus als die Implementierung der Runnable -Schnittstelle. Da Java jedoch nur ein einzelnes Vererbung erlaubt, können Sie nur die Runnable -Schnittstelle implementieren, wenn eine benutzerdefinierte Klasse andere Klassen erben muss.
3.Wie, um einen Prozess in Java zu erstellen
In Java gibt es zwei Möglichkeiten, Prozesse zu erstellen, die insgesamt 5 Hauptklassen umfassen.
Die erste Methode besteht darin, einen Prozess über die Methode der Laufzeit zu erstellen. Sprechen wir über die Unterschiede und Verbindungen zwischen diesen beiden Methoden.
Das erste, worüber ich sprechen möchte, ist die Prozessklasse. Die Prozessklasse ist eine abstrakte Klasse. Es gibt hauptsächlich mehrere abstrakte Methoden. Sie können dies lernen, indem Sie sich den Quellcode der Prozessklasse ansehen:
Befindet sich im java.lang.Process -Pfad:
public class test {public static void main (String [] args) {System.out.println ("Haupt -Thread -ID:"+thread.currentThread (). getId ()); Myrunnable runnable = new Myrunnable (); Thread Thread = neuer Thread (runnable); Thread.Start (); }} class Myrunnable implements runnable {public myrunnable () {} @Override public void run () {System.out.println ("Subhread ID:"+thread.currentThread (). getId ()); }}1) Erstellen Sie einen Prozess über ProcessBuilder
ProcessBuilder ist eine endgültige Klasse mit zwei Konstruktoren:
public Final Class ProcessBuilder {private list <string> Befehl; privates Dateiverzeichnis; private map <String, String> Umgebung; privater boolescher RedirecterrorStream; public processBuilder (list <string> command) {if (command == null) werfen neue nullpointerexception (); this.command = Befehl; } public processBuilder (String ... Befehl) {this.command = new ArrayList <string> (command.length); für (string arg: command) this.command.add (arg); } ......}Der Konstruktor übergibt die Befehlsparameter des Prozesses, der erstellt werden muss. Der erste Konstruktor stellt die Befehlsparameter in die Liste ein und übergibt sie in Form einer unendlich langen Zeichenfolge.
Schauen wir also weiter nach unten. Wie bereits erwähnt, erstellen wir einen neuen Prozess über die Startmethode von ProcessBuilder. Schauen wir uns an, was genau in der Startmethode getan wird. Das Folgende ist der spezifische Implementierungsquellcode der Startmethode:
public Process start () löst IOException {// zuerst in Array konvertieren-eine böswillige Benutzer-Supplied // List könnte versuchen, die Sicherheitsprüfung zu leiten. leerenstring prog = cmDarray [0]; SecurityManager Security = System.getSecurityManager (); if (Sicherheit! String Dir = Verzeichnis == NULL? NULL: DIRECTORY.TOStrING (); Versuchen Sie {return processImpl.start (cmDarray, Umgebung, Dir, RedirecterrorStream);} catch (ioException e) {// Es ist für uns viel einfacher, einen hochwertigen Fehler // Meldung als den Code mit niedrigem Niveau zu erstellen, der das Problem gefunden hat. Neue IOException werfen ("Ich kann nicht das Programm ausführen /" " + prog +" /"" + (dir == null? "Diese Methode gibt ein Prozessobjekt zurück. Der erste Teil der Methode entspricht dem Einstellen einiger Parameter basierend auf den Befehlsparametern und dem Set -Arbeitsverzeichnis. Das Wichtigste ist ein Satz im Block Anweisungsblock:
return processImpl.Start (CMDarray, Umgebung, Dir, RedirecterrorStream);
Dies ist der Satz, der den Prozess wirklich erstellt. Beachten Sie, dass die Startmethode der ProcessImpl -Klasse aufgerufen wird. Hier können wir wissen, dass Start eine statische Methode sein muss. Also, was für prozessimpl? Diese Klasse befindet sich auch im Pfad java.lang.Processimpl. Schauen wir uns die spezifische Implementierung dieser Klasse an:
ProcessImpl ist auch eine endgültige Klasse, die die Prozessklasse erbt:
Final Class ProcessImpl erweitert den Prozess (// systemabhängigem Teil des processBuilder.start () statischen Prozessstarts (String cmDarray [], java.util.map <String> Umgebung, String Dir, boolean redirecterrorstream). Return New ProcessImpl (CMDarray, Envblock, Dir, RedirecterrorStream); } ....}
Dies ist die spezifische Implementierung der Startmethode der ProcessImpl -Klasse. Tatsächlich wird dieser Satz verwendet, um ein processImpl -Objekt zu erstellen:
Return New ProcessImpl (CMDarray, Envblock, Dir, RedirecterrorStream);
In ProcessImpl werden mehrere abstrakte Methoden in der Prozessklasse in der konkreten Implementierung implementiert.
Tatsächlich wird ein ProcessImpl -Objekt über die Startmethode von ProcessBuilder erstellt.
Schauen wir uns das Beispiel der Verwendung von ProcessBuilder an, um einen Prozess zu erstellen. Wenn ich beispielsweise einen Prozess über ProcessBuilder starten möchte, um CMD zu öffnen und IP -Adressinformationen zu erhalten, kann ich ihn so schreiben:
public class test {public static void main (String [] args) löst IOException aus {processBuilder pb = new ProcessBuilder ("cmd", "/c", "ipconfig/all"); Prozessprozess = pb.start (); Scanner scanner = neuer Scanner (process.getInputStream ()); while (scanner.hasnextline ()) {System.out.println (scanner.nextline ()); } scanner.close (); }}Der erste Schritt ist der kritischste, nämlich die Befehlszeichenfolge an den ProcessBuilder -Konstruktor übergeben. Im Allgemeinen wird jeder unabhängige Befehl in der Zeichenfolge als separater Parameter verwendet, kann aber auch in die Liste in der Reihenfolge platziert und übergeben werden.
In vielen anderen spezifischen Verwendungen werde ich hier nicht näher erläutern, z. Interessierte Freunde können die entsprechenden API -Dokumente anzeigen.
2) Erstellen Sie einen Prozess über die EXEC -Methode von Runtime
Schauen wir uns zunächst die spezifische Implementierung der Laufzeitklasse und der Exec -Methode an. Die Laufzeit repräsentiert, wie der Name schon sagt, die Instanz der virtuellen Maschine, in der sich der aktuelle Prozess befindet.
Da ein Prozess nur in einer virtuellen Maschineninstanz ausgeführt wird, wird in der Laufzeit ein Singleton -Modus verwendet, dh nur eine virtuelle Maschineninstanz wird generiert:
öffentliche Klasse Runtime {private statische Laufzeit currentRuntime = new runtime (); /*** Gibt das Laufzeitobjekt zurück, das der aktuellen Java -Anwendung zugeordnet ist. * Die meisten Methoden der Klasse <Code> Laufzeit </code> sind Instanz * Methoden und müssen in Bezug auf das aktuelle Laufzeitobjekt aufgerufen werden. * * @return das <code> laufzeit </code> Objekt, die der aktuellen * Java -Anwendung zugeordnet sind. */ public statische Laufzeit getruntime () {return CurrentRuntime; } / ** Lassen Sie niemanden diese Klasse instanziieren* / private runTime () {} ...}Von hier aus können wir sehen, dass wir, da der Konstruktor der Laufzeitklasse privat ist, die Laufzeitinstanz nur durch GetRuntime erhalten können. Schauen wir uns als nächstes die Implementierung der EXEC -Methode genauer an. In Laufzeit gibt es mehrere verschiedene Überlastimplementierungen von EXEC, aber das Ende der Ausführung ist diese Version der EXEC -Methode:
public Process exec (String [] cmDarray, String [] Envp, Datei Dire) löst IOException {neuer Prozessbuilder zurück (cmDarray) .Environment (envp) .Directory (Dir) .Start (); }Es ist festzustellen, dass der Prozess tatsächlich durch die Startmethode der ProcessBuilder -Klasse erstellt wird, wenn der Prozess durch den Exec der Laufzeitklasse erstellt wird.
Schauen wir uns ein Beispiel an, um zu sehen, wie Sie einen Prozess über den Exec von Runtime erstellen, oder um das vorherige Beispiel auf CMD zu erstellen, um IP -Adressinformationen zu erhalten:
public class test {public static void main (String [] args) löst IOException aus {String cmd = "cmd"+"/c"+"ipconfig/all"; Process process = runTime.getRuntime (). Exec (cmd); Scanner scanner = neuer Scanner (process.getInputStream ()); while (scanner.hasnextline ()) {System.out.println (scanner.nextline ()); } scanner.close (); }}Es ist zu beachten, dass die EXEC-Methode keine Parameter für unbestimmte Länge unterstützt (ProcessBuilder unterstützt Parameter für unbestimmte Länge), sodass die Befehlsparameter zuerst gespleißt werden müssen, bevor sie eingeben.
Ich werde vorerst darüber sprechen, wie man Themen und Prozesse in Java erstellt. Interessierte Freunde können auf relevante Informationen verweisen.