Die umfassendste Analyse der Verwendung von Java Multithreading. Wenn Sie keine eingehende Forschung über den Multithreading-Mechanismus von Java durchgeführt haben, kann dieser Artikel Ihnen helfen, die Prinzipien und Verwendungsmethoden des Java-Multithreading gründlicher zu verstehen.
1. Erstellen Sie einen Thread
Es gibt zwei Möglichkeiten, Threads in Java zu erstellen: Verwenden der Thread -Klasse und der Runnable -Schnittstelle. Wenn Sie die Runnable -Schnittstelle verwenden, müssen Sie eine Thread -Instanz erstellen. Unabhängig davon, ob Sie einen Thread durch die Thread -Klasse oder die Runnable -Schnittstelle einrichten, müssen Sie eine Instanz der Thread -Klasse oder ihrer Unterklasse festlegen. Fadenkonstruktor:
Methode 1: Erben Sie die Thread -Klasse und überschreiben Sie die Run -Methode
public class threadDemo1 {public static void main (String [] args) {Demo d = new Demo (); D.Start (); für (int i = 0; i <60; i ++) {System.out.println (Thread.currentThread (). getName ()+i); }}} class Demo erweitert Thread {public void run () {für (int i = 0; i <60; i ++) {System.out.println (Thread.currentThread (). getName ()+i); }}}Methode 2:
public class threadDemo2 {public static void main (String [] args) {Demo2 d = new Demo2 (); Thread t = neuer Thread (d); t.start (); für (int x = 0; x <60; x ++) {System.out.println (thread.currentThread (). getName ()+x); }}} class Demo2 implementiert runnable {public void run () {for (int x = 0; x <60; x ++) {System.out.println (Thread.CurrentThread (). getName ()+x); }}}2. Der Lebenszyklus von Fäden
Genauso wie Menschen Geburt, Alter, Krankheit und Tod haben, müssen auch Fäden vier verschiedene Staaten durchlaufen: Beginnen (warten), rennen, aufhören und stoppen. Alle vier Zustände können mit Methoden in der Thread -Klasse gesteuert werden. Das Folgende ist eine Methode, die sich auf diese vier Zustände in der Thread -Klasse bezieht.
// Thread starten
Publicvoid start ();
Publicvoid Run ();
// Fäden aussetzen und aufwachen
Publicvoid Resume (); // nicht empfohlen zu verwenden
Publicvoid suspend (); // nicht empfohlen zu verwenden
PublicStaticvoid Sleep (Long Millis);
PublicStaticvoid Sleep (Long Millis, int Nanos);
// den Thread beenden
Publicvoid Stop (); // nicht empfohlen zu verwenden
Publicvoid Interrupt ();
// den Thread -Status erhalten
Publicboolean ISALIVE ();
PublicBoolean ist uneingeschränkt ();
PublicStaticboolean unterbrbse ();
// Methode beibringen
Publicvoid Join () wirft InterruptedException aus;
Nachdem der Thread festgelegt wurde, wird der Code in der Auslaufmethode nicht sofort ausgeführt, sondern befindet sich in einem Wartezustand. Wenn sich der Thread in einem Wartezustand befindet, können Sie die Thread -Klasse -Methode verwenden, um verschiedene Eigenschaften des Threads festzulegen, z.
Nach dem Aufrufen der Startmethode beginnt der Thread mit der Ausführung des Codes in der Ausführungsmethode. Der Thread tritt in den laufenden Zustand ein. Sie können die ISALIVE -Methode der Thread -Klasse verwenden, um festzustellen, ob sich der Thread im laufenden Zustand befindet. Wenn sich der Thread im laufenden Zustand befindet, kehrt Isalive wahr zurück. Wenn Isalive falsch zurückgibt, kann sich der Thread im Wartezustand oder im Stoppstatus befinden. Der folgende Code demonstriert die Umstellung zwischen den drei Zuständen des Erstellens, Ausführens und Stoppens von Threads und gibt den entsprechenden ISALIVE -Rückgabewert aus.
Sobald der Thread mit der Ausführung der Ausführungsmethode beginnt, wird der Thread erst beendet, wenn die Ausführungsmethode ausgeführt wird. Während der Ausführung eines Threads kann der Thread jedoch mit zwei Methoden vorübergehend gestoppt werden. Diese beiden Methoden sind suspendiert und schlafen. Nach dem Suspendieren des Fadens mit Suspend kann der Faden durch die Lebenslaufmethode geweckt werden. Nach dem Schlaf zum Schlafen kann der Faden nach der festgelegten Zeit nur in den Bereitschaftszustand gesteckt werden (nach dem Thread schliefen der Thread möglicherweise nicht sofort, sondern läuft nur in den fertigen Zustand und wartet darauf, dass das System plant).
Bei der Verwendung der Schlafmethode gibt es zwei Dinge zu beachten:
1. Die Schlafmethode hat zwei Überlastformulare. Eine der Überlastungsformulare kann nicht nur auf Millisekunden, sondern auch auf Nanosekunden festgelegt werden (1.000.000 Nanosekunden entsprechen 1 Millisekunde). Java -virtuelle Maschinen auf den meisten Betriebssystemplattformen können jedoch nicht für Nanosekunden genau sein. Wenn also Nanosekunden für den Schlaf eingestellt sind, nimmt die java virtuelle Maschine die Millisekunden, die diesem Wert am nächsten kommt.
2. Wenn Sie die Schlafmethode verwenden, müssen Sie Würfe verwenden oder {…} catch {…} versuchen. Da die Run -Methode keine Würfe verwenden kann, können Sie nur Try {…} catch {…} verwenden. Wenn der Faden schläft, wirft der Schlaf eine InterruptedException -Ausnahme aus, wenn der Faden mithilfe der Interrupt -Methode unterbrochen wird. Die Schlafmethode ist wie folgt definiert:
PublicStaticvoid Sleep (Long Millis) wirft die InterruptedException aus
publicStaticvoid -Schlaf (Long Millis, Int Nanos) wirft die InterruptedException aus
Es gibt drei Möglichkeiten, den Thread zu beenden.
1. Verwenden Sie das Ausgangsflag, um den Gewinde normal zu beenden, dh der Gewinde endet, wenn die Auslaufmethode abgeschlossen ist.
2. Verwenden Sie die Stoppmethode, um den Thread zwangs zu enden (diese Methode wird nicht empfohlen, da der Stopp mit Aussetzung und Lebenslauf gleich ist und möglicherweise auch unvorhersehbare Ergebnisse haben).
3. Verwenden Sie die Interrupt -Methode, um den Thread zu unterbrechen.
1. Verwenden Sie das Ausgangsflag, um den Faden zu beenden
Wenn die Run -Methode ausgeführt wird, wird der Thread beendet. Aber manchmal endet die Run -Methode nie. Beispielsweise verwenden Sie Threads, um Client -Anforderungen in Serverprogrammen oder anderen Aufgaben anzuhören, die die Schleifenverarbeitung erfordern. In diesem Fall werden diese Aufgaben normalerweise in einer Schleife platziert, z. B. während der Schleife. Wenn Sie möchten, dass die Schleife für immer läuft, können Sie verwenden, während (true) {…} damit umgehen kann. Wenn Sie jedoch unter einer bestimmten Bedingung den Aufenthalt des Schleifens durchführen möchten, besteht die am stärksten direkte Möglichkeit darin, ein boolesches Flag einzustellen und zu steuern, ob die While -Schleife dieses Flag auf True oder False einstellen. Hier ist ein Beispiel für die Beendigung eines Fadens mit dem Ausgangsflag.
Die Funktion der Join -Methode besteht darin, den asynchronen Ausführungs -Thread in synchrone Ausführung zu verwandeln. Das heißt, wenn die Startmethode der Thread -Instanz aufgerufen wird, wird die Methode sofort zurückgegeben. Wenn ein von diesem Thread berechnetes Wert verwendet werden muss, nachdem die Startmethode aufgerufen wurde, muss die Join -Methode verwendet werden. Wenn Sie die Join -Methode nicht verwenden, kann nicht garantiert werden, dass der Thread ausgeführt wird, wenn eine Anweisung hinter der Startmethode ausgeführt wird. Nach der Verwendung der Join -Methode wird das Programm erst ausgeführt, wenn der Thread beendet ist. Der folgende Code zeigt die Verwendung von Join.
3.. Multithread -Sicherheitsprobleme
Ursache des Problems: Wenn mehrere Anweisungen auf demselben Thread arbeiten, um Daten zu teilen, führt ein Thread nur einen Teil mehrerer Anweisungen aus, hat jedoch noch nicht fertiggestellt, und ein anderer Thread nimmt an der Ausführung teil, was zu einem Fehler beim Teilen von Daten führt.
Lösung: Für mehrere Anweisungen, die Daten mit mehreren Operationen teilen, kann nur ein Thread ausgeführt werden. Während des Ausführungsprozesses werden andere Threads nicht ausgeführt.
Codeblockungen synchronisieren:
public class ThreadDemo3 {public static void main (String [] args) {Ticket t = new Ticket (); Thread T1 = neuer Thread (t, "Fenster eins"); Thread T2 = neuer Thread (t, "Fenster zwei"); Thread T3 = neuer Thread (t, "Fenster drei"); Thread T4 = neuer Thread (t, "Fenster vier"); t1.start (); t2.Start (); t3.Start (); t4.Start (); }} Klasse Ticket implementiert runnable {private int ticket = 400; public void run () {while (true) {synchronized (new Object ()) {try {thread.sleep (1); } catch (InterruptedException e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } if (Ticket <= 0) Break; System.out.println (Thread.currentThread (). GetName ()+"--- verkaufen"+Ticket--); }}}}Synchronfunktionen
public class ThreadDemo3 {public static void main (String [] args) {Ticket t = new Ticket (); Thread T1 = neuer Thread (t, "Fenster eins"); Thread T2 = neuer Thread (t, "Fenster zwei"); Thread T3 = neuer Thread (t, "Fenster drei"); Thread T4 = neuer Thread (t, "Fenster vier"); t1.start (); t2.Start (); t3.Start (); t4.Start (); }} Klasse Ticket implementiert runnable {private int ticket = 4000; public synchronisierte void saletticket () {if (ticket> 0) system.out.println (Thread.currentThread (). getName ()+"verkauft"+Ticket-); } public void run () {while (true) {saletticket (); }}}Synchronous -Funktionssperrung ist diese statische Synchronisationsfunktionsschloss ist die Klasse
Kommunikation zwischen Themen
public class ThreadDemo3 {public static void main (String [] args) {Klasse Person {public String name; privates String -Geschlecht; public void set (String -Name, String -Geschlecht) {this.name = name; this.Geper = Geschlecht; } public void get () {System.out.println (this.name+"...."+this.GerStender); }} endgültige Person p = neue Person (); neuer Thread (new Runnable () {public void run () {int x = 0; while (true) {if (x == 0) {P.Set ("Zhang san", "männlich");} else {P.Set ("lili", "nv");} x = (x+1)%2; neuer Thread (new Runnable () {public void run () {while (true) {p.get ();}}}). start (); }}/ *Zhang san .... männlicher Zhang San ... männliche Lili .... nvlili .... männlicher Zhang San .... nvlili .... männlich */Ändern Sie den obigen Code
public class ThreadDemo3 {public static void main (String [] args) {Klasse Person {public String name; privates String -Geschlecht; public void set (String -Name, String -Geschlecht) {this.name = name; this.Geper = Geschlecht; } public void get () {System.out.println (this.name+"...."+this.GerStender); }} endgültige Person p = neue Person (); neuer Thread (new Runnable () {public void run () {int x = 0; while (true) {synchronized (p) {if (x == 0) {P.Set ("Zhang san", "männlich");} else {p.set ("lili", "nv");} (x+1); neuer Thread (new Runnable () {public void run () {while (true) {synchronized (p) {p.get ();}}}}). start (); }} /* lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili ... nv zhang zhang San .... männlicher Zhang San ... männlich */Warten auf den Weckmechanismus
/**Thread Warted Wake-up Mechanismus*Warten und Aufwachen müssen das gleiche Schloss sein public static void main (String [] args) {Klasse Person {public String name; privates String -Geschlecht; public void set (String -Name, String -Geschlecht) {this.name = name; this.Geper = Geschlecht; } public void get () {System.out.println (this.name+"...."+this.GerStender); }} endgültige Person p = neue Person (); New Thread (new Runnable () {public void run () {int x = 0; while (true) {synchronized (p) {if (flags) try {p.wait ();} catch (interruptedException e) {// todo auto-generiertes Catch Block E. printacktrace ();}; } else {P.Set ("lili", "nv"); neuer Thread (new Runnable () {public void run () {while (true) {synchronized (p) {if (! flags) try {p.wait ();} catch (interruptedException e) {// todo auto-generiertes block e.printstacktrace ();}; P.); }).Start(); }}Produktions- und Verbrauchsmechanismus eins
öffentliche Klasse ThreadDemo4 {private statische boolesche Flaggen = Falsch; public static void main (String [] args) {Klasse Waren {private String -Name; private int num; public synchronisierte void produzieren (String name) {if (flags) try {wait (); } catch (InterruptedException e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } this.name = name+"number:"+num ++; System.out.println ("produziert ......"+this.name); Flags = wahr; notifyAll (); } public synchronisierte void Consumption () {if (! Flags) versuchen {Wait (); } catch (InterruptedException e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } System.out.println ("konsumiert *****"+name); Flags = falsch; notifyAll (); }} endgültige Waren g = neue Waren (); neuer Thread (new Runnable () {public void run () {while (true) {g.produce ("produkt");}}}). start (); neuer Thread (new Runnable () {public void run () {while (true) {g.consume ();}}}). start (); }}Produktions- und Verbrauchsmechanismus 2
öffentliche Klasse ThreadDemo4 {private statische boolesche Flaggen = Falsch; public static void main (String [] args) {Klasse Waren {private String -Name; private int num; public synchronisierte void produzieren (String name) {while (flags) try {wait (); } catch (InterruptedException e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } this.name = name+"number:"+num ++; System.out.println (Thread.currentThread (). GetName ()+"produziert ..."+this.name); Flags = wahr; notifyAll (); } public synchronisierte void conteum () {while (! Flags) versuchen {Wait (); } catch (InterruptedException e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } System.out.println (Thread.currentThread (). GetName ()+"konsumiert *******"+Name); Flags = falsch; notifyAll (); }} endgültige Waren g = neue Waren (); New Thread (new Runnable () {public void run () {while (true) {g.produce ("produkt");}}}, "produzieren (" produkt ");}}}," produzieren ("produkt");}}}, "produzieren"); }, "Verbraucher Nr. 1"). Start (); Konsumiert ******* Commodity -Nummer: 48050 Producer Nr. 1 produziert ... Warennummer: 48051Consumer Nr. 2 Konsumiert ****. 48053Consumer No. 48055*/Das obige ist die Zusammenstellung von Java-Multi-Thread-Informationen. Wir werden in Zukunft weiterhin relevantes Wissen hinzufügen. Vielen Dank für Ihre Unterstützung für diese Seite!