1. Fäden und Prozesse
1. Was ist der Unterschied zwischen Thread und Prozess:
Ein Thread bezieht sich auf eine Ausführungseinheit, die den Programmcode während der Ausführung ausführen kann. In der Java -Sprache haben Threads vier Staaten: Laufen, Bereit, Suspend und Ende.
Ein Prozess bezieht sich auf ein Programm, das ausgeführt wird. Themen werden auch zu leichten Prozessen geworden, wenn sie etwas zu tun haben. Sie haben die kleinste Programmausführung. Ein Prozess kann mehrere Threads haben. Jeder Thread teilt den internen Energieraum des Programms (Codesegmente, Datensegmente und Haufen Speicherplatz) und einige Ressourcen auf Prozessebene (z. B. offene Dateien), aber jeder Thread hat seinen eigenen Speicherplatz.
2. Warum Multi-Process verwenden ?
- Die Verwendung von Multi-Threading kann die Reaktionszeit des Programms verkürzen. Wenn ein Betrieb zeitaufwändig ist oder in langer Wartezeit steckt, reagiert das Programm nicht auf Operationen wie Maus und Tastatur. Nach der Verwendung von Multi-Threading kann dieser zeitaufwändige Thread einem separaten Thread für die Ausführung zugeordnet werden, wodurch das Programm zu einer besseren Interaktivität führt.
- Die Erstellung und das Schalten von Threads und das Schalten sind im Vergleich zu Prozessen günstiger, während Multithreading die Datenaustausch sehr effizient ist.
-Multi-CPU- oder Multi-Core-Computer können Multi-Threads ausführen. Wenn ein einzelner Prozess verwendet wird, werden die Computerressourcen nicht wiederverwendet, was zu enormen Ressourcenverschwendung führt. Die Verwendung von Multithreading auf Multi-CPU-Computern kann die CPU-Nutzung verbessern.
- Die Verwendung von Multithreading kann die Struktur des Programms vereinfachen und es leicht zu verstehen und zu warten.
2. Erstellen von Threads <BR /> Es gibt im Allgemeinen drei Methoden zur Multi-Threading-Implementierung, und die ersten beiden sind die am häufigsten verwendeten Methoden:
1. Erben Sie die Thread -Klasse und überschreiben Sie die Run () -Methode
Thread ist im Wesentlichen eine Instanz, die die runnable Schnittstelle implementiert. Es ist zu beachten, dass nach dem Aufrufen der Start () -Methode Multi-Threaded-Code nicht sofort ausgeführt wird, sondern den Thread ausgeführt wird. Wenn der Code mit Multi-Threaded-Code ausgeführt wird, wird das Betriebssystem bestimmt.
Hier sind die Hauptschritte:
(1) Definieren Sie die Unterklasse der Thread -Klasse und überschreiben Sie die Auslaufmethode der Klasse. Die Methodekörper der Run -Methode repräsentiert die Aufgabe, die der Thread ausführen möchte. Daher wird die Run () -Methode als Ausführungskörper bezeichnet.
(2) Erstellen Sie eine Instanz der Thread -Unterklasse, dh ein Thread -Objekt.
(3) Rufen Sie die Start () -Methode des Thread -Objekts auf, um den Thread zu starten.
public class testThread erweitert Thread {public void run () {System.out.println ("Hello World"); } public static void main (String [] args) {thread mthread = new TestThread (); Mthread.Start (); }} 2. Implementieren Sie die Runnable -Schnittstelle und implementieren Sie die Run () -Methode der Schnittstelle
Hier sind die Hauptschritte:
(1) Passen Sie die Klasse an und implementieren Sie die Runnable -Schnittstelle und implementieren Sie die Run () -Methode.
(2) Erstellen Sie eine Instanz der Thread -Unterklasse und instanziieren Sie das Thread -Objekt mit dem Objekt, das die Runnable -Schnittstelle als Parameter implementiert.
(3) Rufen Sie die Start () -Methode des Threads auf, um den Thread zu starten.
public class testrunnable implements runnable {public void run () {System.out.println ("Hallo Welt"); }} public class testrunnable {public static void main (String [] args) {testrunnable mTestrunnable = new TestRunnable (); Thread mthread = neuer Thread (MTestrunnable); Mthread.Start (); }} 3. Implementieren Sie die Callable -Schnittstelle und überschreiben Sie die Call () -Methode
Die Callable -Schnittstelle ist tatsächlich eine Funktionsklasse im Ausführungsrahmen. Die Callable -Schnittstelle ähnelt der Runnable -Schnittstelle, bietet jedoch leistungsstärkere Funktionen als Runnable, die sich hauptsächlich in den folgenden 3 Punkten manifestieren:
(1) Callable kann nach der Annahme der Aufgabe einen Rückgabewert liefern, und Runnable kann diese Funktion nicht bereitstellen.
(2) Die CALL () -Methode in Callable kann Ausnahmen auslösen, während die Run () -Methode von Runnable keine Ausnahmen auslösen kann.
(3) Callable kann ein zukünftiges Objekt erhalten. Das zukünftige Objekt repräsentiert das Ergebnis der Berechnung von Ibrahimovic und erstellt eine Methode, um zu überprüfen, ob die Berechnung abgeschlossen ist. Da der Thread zu einem asynchronen Berechnungsmodell gehört, ist es unmöglich, den Rückgabewert der Funktion aus anderen Threads zu erhalten. In diesem Fall kann die Zukunft verwendet werden, um die Methode call () zu überwachen, wenn der Ziel -Thread die CALL () -Methode aufruft. Wenn jedoch die zukünftige Get () -Methode aufgerufen wird, um das Ergebnis zu erhalten, blockiert und kennt der aktuelle Thread das Rückgabeergebnis der Call () -Methode.
public class testcallable {// Thread -Klasse erstellen öffentlich statische Klasse MyTestCallable Implements Callable {public String call () löst Ausnahme aus {retune "Hallo Welt"; }} public static void main (String [] args) {myTestCallable mmyTestCallable = new myTestCallable (); ExecutorService mexecutorService = Executors.newsinglethreadpool (); Zukünftige mfuture = mexecutorservice.submit (mmyTestCallable); Versuchen Sie, das Ergebnis system.out.println (mfuture.get ()) zu beenden und zurückzugeben; } catch (Ausnahme e) {e.printstacktrace (); }}}Das Ausgabeergebnis des obigen Programms lautet: Hallo Welt
Unter diesen drei Methoden wird im Allgemeinen empfohlen, die Runnable -Schnittstelle zu implementieren. Der Grund ist: Erstens definiert die Thread -Klasse eine Vielzahl von Methoden, die durch abgeleitete Klassen umgeschrieben werden können, aber nur die Run () -Methode muss umgeschrieben werden, wodurch die Hauptfunktion dieses Threads realisiert wird, die auch die Methode ist, die zur Implementierung der Runnable -Schnittstelle erforderlich ist. Zweitens sollte eine Klasse geerbt werden, wenn sie gestärkt oder modifiziert werden müssen. Wenn daher keine anderen Methoden der Thread -Klasse überschrieben werden müssen, ist es in diesem Fall besser, die Runnable -Schnittstelle zu implementieren.
3.. Interrupt Thread <BR /> Der Thread beendet, wenn die Run () -Methode des Threads die letzte Anweisung in der Methode -Körperschaft ausführt und durch Ausführung der Rückgabeanweisung zurückgibt oder wenn eine Ausnahme, die nicht in der Methode gefangen ist, nicht erfasst wird. In früheren Versionen von Java gab es eine Stop -Methode, die andere Threads aufrufen konnten, um den Thread zu beenden, aber diese Methode wurde nun veraltet.
Die Interrupt -Methode kann verwendet werden, um die Beendigung des Threads anzufordern. Wenn ein Thread die Interrupt -Methode aufruft, wird der Interrupt -Status des Threads festgelegt. Dies ist die Boolesche Flagge, die kein Thread hat. Jeder Thread sollte dieses Flag von Zeit zu Zeit überprüfen, um festzustellen, ob der Thread unterbrochen wird.
Um herauszufinden, ob der Thread eingestellt ist, können Sie Thread.CurrentThread () aufrufen.
while (! thread.currentThread (). is interrupted ()) {mach etwas} Wenn jedoch ein Thread blockiert ist, kann der Interrupt -Zustand nicht erkannt werden. Hier wird die InterruptedException erzeugt. Wenn eine Interrupt -Methode auf einen blockierten Faden aufgerufen wird (Schlaf oder Wartezeit). Der Blockierungsanruf wird durch die InterruptedException unterbrochen.
Wenn die Schlafmethode (oder eine andere unterbrochene Methode) nach jeder Iteration aufgerufen wird, ist die Erkennung von Isinrupted unnötig und nutzlos. Wenn die Schlafmethode aufgerufen wird, wenn der Interrupt -Zustand festgelegt ist, schläft sie nicht, sondern löscht den Zustand und wirft eine InterruptedException aus. Wenn Sie also den Schlaf in einer Schleife nennen, erkennen Sie den Interrupt -Status nicht, sondern fangen Sie einfach die InterruptedException an.
In vielen veröffentlichten Codes werden Sie feststellen, dass die InterruptedException auf sehr niedriger Ebene unterdrückt wird:
void mytask () {... try {sleep (50)} catch (InterruptedException e) {...}}Tu das nicht. Wenn Sie nicht glauben, dass es einen Vorteil in einem Haken gibt, gibt es zwei angemessene Optionen:
Rufen Sie Thread.CurrentThread (). Interrup () in Catch auf, um den Interrupt -Status festzulegen. Anrufer können es erkennen. Eine bessere Option ist die Verwendung von Throwten -InterruptedException, um Ihre Methode zu markieren, ohne die Aussage -Anweisungsblöcke zu verwenden, um die abgeschlossene zu erfassen. Auf diese Weise kann der Anrufer diese Ausnahme aufnehmen:
void mytask () throwvruptedException {schlaf (50)}4. Der Zustand des Threads
(1). Neuer Status (neu): Es wird ein neues Thread -Objekt erstellt.
(2). Ready State (Runnable): Nachdem das Thread -Objekt erstellt wurde, rufen andere Threads die Start () -Methode des Objekts auf. Der Thread in diesem Zustand befindet sich im Runnable -Thread -Pool und wird laufbar. Es wartet darauf, die CPU -Nutzungsrechte zu erhalten.
(3). Auslaufstatus: Der Thread im Ready State erwirbt die CPU und führt den Programmcode aus.
(4). Blockierter Zustand: Blockierter Zustand bedeutet, dass der Thread die CPU -Nutzungsrechte aus irgendeinem Grund aufgibt und vorübergehend aufhört zu laufen. Erst wenn der Thread in den bereiten Zustand eingeht, hat er die Chance, in den Laufstatus zu gehen. Es gibt drei Arten von Blockaden:
- Warten auf Block: Der laufende Thread führt die Wait () -Methode aus, und der JVM steckt den Thread in den Wartepool.
.
- Andere Blockierung: Wenn ein laufender Thread die Methode Sleep () oder Join () ausführt oder eine E/A -Anforderung ausgibt, setzt der JVM den Thread in einen Blockierstatus. Wenn der Sleep () -State zeitlich abgestimmt war, Join () darauf wartete, dass der Faden endet oder zeitlich abgestimmt hat oder die E/A-Verarbeitung abgeschlossen wurde, wurde der Thread wieder in den bereiten Zustand eingegeben.
(5). Dead State: Der Thread hat die Ausführung der Run () -Methode aufgrund einer Ausnahme abgeschlossen oder beendet, und der Thread beendet seinen Lebenszyklus.
5. Fadenpriorität und Daemon -Thread
1. Fadenpriorität
In Java hat jeder Thread eine Priorität, und standardmäßig erbt ein Thread die Priorität seiner übergeordneten Klasse. Sie können die SetPriority -Methode verwenden, um die Priorität von Faden zu erhöhen oder zu verringern. Die Priorität kann auf jeden Wert zwischen min_priorität (definiert als 1 in der Thread -Klasse) und max_priority (definiert als 10 in der Thread -Klasse) eingestellt werden. Die Standardpriorität von Threads ist Norm_Priority (definiert als 5 in der Thread -Klasse).
Versuchen Sie, sich nicht auf Priorität zu verlassen. Wenn Sie es wirklich verwenden möchten, sollten Sie einen häufigen Fehler vermeiden, den Anfänger machen. Wenn mehrere Threads mit hoher Priorität nicht in den inaktiven Zustand eintreten, werden Threads mit niedriger Priorität möglicherweise niemals ausgeführt. Immer wenn der Scheduler beschließt, einen neuen Thread auszuführen, wählt er zunächst mit Priorität unter den Threads aus, obwohl dies die Threads mit niedriger Priorität vollständig verhungert.
2. Daemon -Thread
Rufen Sie SetDaemon (True) an; Konvertiert den Faden in einen Daemon -Thread. Der einzige Zweck von Daemon -Threads ist die Bereitstellung von Diensten für andere Threads. Der Timing -Thread ist ein Beispiel. Es sendet Signale regelmäßig an andere Threads oder löscht veraltete Threads, die Cache -Elemente angeben. Wenn nur Daemon -Threads übrig sind, beendet die virtuelle Maschine, denn wenn nur Daemon -Threads übrig sind, müssen das Programm nicht weiter ausgeführt werden.
Darüber hinaus sind die Müllsammlung, die Speicherverwaltung und andere Threads von JVM Daemon -Threads. Bei Datenbankanwendungen enthält der verwendete Datenbankverbindungspool auch viele Hintergrund -Threads, die die Anzahl der Verbindungen, Zeitüberschreitungszeit, Status usw. überwachen, usw.
Das obige handelt von der Thread -Definition, dem Zustand und den Eigenschaften von Java multithreading. Ich hoffe, es wird für das Lernen aller hilfreich sein.