Dieser Artikel untersucht hauptsächlich Probleme von Hintergrund -Threads in Java wie folgt.
Ich habe noch nie davon gehört, dass es Hintergrund -Threads in Java gibt. Im Allgemeinen enthält JVM (Java Virtual Machine) im Allgemeinen zwei Arten von Threads, nämlich Benutzer -Thread und Hintergrund -Thread. Der sogenannte Daemon-Thread bezieht sich auf einen Thread, der beim Ausführen des Programms einen gemeinsamen Service im Hintergrund bietet, und dieser Thread ist kein unverzichtbarer Bestandteil des Programms. Wenn alle Nicht-Background-Threads enden, dann, wenn die Benutzerfäden enden, endet das Programm. Gleichzeitig tötet es alle Hintergrund -Threads im Prozess ab. Umgekehrt endet das Programm nicht, solange alle Nicht-Rückkling-Threads noch ausgeführt werden. Es ist besser, Main () auszuführen als ein Nicht-Rückschlag-Thread.
Basierend auf dieser Funktion, wenn alle Benutzer -Threads im Virtual Machine -Ausgang vom Ausführen beenden, hat der Daemon -Thread keine Serviceobjekte, beendet der JVM.
Dies wird im JDK -Quellcode erklärt.
* Markiert diesen Thread entweder als {@linkplain #isdaemon Daemon} Thread
* oder ein Benutzer -Thread. Die virtuelle Java -Maschine verlässt die einzige
* Threads, die ausgeführt werden, sind alle Daemon -Threads.
1. Bedingungen für den Start eines Hintergrund -Threads:
/*Die Methode setDaemon () muss aufgerufen werden, bevor der Thread gestartet wird, um diesen Thread als Hintergrund -Thread festzulegen. * In diesem Programm wird nach der Eingabe einer Zeichenfolge der Haupt -Thread nicht mehr ausgeführt* Es gibt keinen Thread für den Benutzer, der im Programm ausgeführt werden kann. Der Hintergrund -Thread wird also gestoppt. Daemon = neuer Thread (neuer Daemonrunner ()); Daemon.setDaemon (true); Dämon.start (); Scanner s = neuer Scanner (System.in); String String = s.Nextline (); {TimeUnit.Milliseconds.sleep (50);} catch (InterruptedException e) {e.printstacktrace ();}}});}}2. Alle Threads im Hintergrund -Thread gehören zum Hintergrund -Thread. Obwohl Sie nicht explizit angeben, dass es sich um Hintergrund -Threads handelt, sind es tatsächlich Hintergrund -Threads.
/* Sie können bestimmen, ob der Thread ein Hintergrund -Thread ist, indem Sie die Methode isdaemon () aufrufen. Wenn es sich um einen Hintergrund -Thread * handelt, wird in diesem Beispiel ein beliebiger Thread automatisch auf den Hintergrund -Thread * gesetzt. In diesem Beispiel wird der Daemon -Thread auf den Hintergrundmodus eingestellt und leitet dann viele untergeordnete Threads ab. Diese Threads sind nicht auf den * Hintergrundmodus eingestellt, aber sie sind in der Tat Hintergrund -Threads. Dann tritt der Daemon -Thread in eine unendliche Schleife ein und ruft die Ertragsmethode in der Schleife* auf, um die Steuerung an andere Threads oder Prozesse zu übergeben. Daemonspawn ()); t [i] .Start (); System.out.println ("Daemonspawn" + i + "gestartet");} für (int i = 0; i <t.length; i ++) {System.out.println ("t [" + i + "] .isdaemon + t [i] .Isdaemon. {Thread.yield();}}}class DaemonSpawn implements Runnable{@Override public void run() {while (true) {Thread.yield();}}}public class Daemons {public static void main(String[] args) {Thread d = new Thread(new Daemon ()); D.Setdaemon (true); D.Start (); System.out.println ("d.isdaemon () =" + d.isdaemon (); try {TimeUnit.seconds.sleep (1); // Lassen Sie den Thread im Start -up -Hintergrund eine bestimmte Ausführungszeit erhalten. } catch (InterruptedException e) {e.printstacktrace ();}}}Die endgültigen Ausführungsergebnisse sind wie folgt:
d.isdaemon () = true
Daemonspawn 0Started
Daemonspawn 1Started
Daemonspawn 2Started
Daemonspawn 3Started
Daemonspawn 4Started
Daemonspawn 5Started
Daemonspawn 6Started
Daemonspawn 7Started
Daemonspawn 8Started
Daemonspawn 9Started
T [0] .isdaemonTrue
T [1] .isdaemonTrue
T [2] .isdaemonTrue
T [3] .isdaemonTrue
T [4] .isdaemonTrue
T [5] .isdaemonTrue
T [6] .isdaemonTrue
T [7] .isdaemonTrue
T [8] .isdaemonTrue
T [9] .isdaemonTrue
A. Geben Sie ein ThreadFactory -Objekt an, indem Sie Executors.newCachedThreadPool() Methoden angeben. Auf diese Weise können wir auch den Thread einstellen, den wir als Hintergrund -Thread beginnen möchten.
/* In diesem Beispiel für diesen statischen Konstruktor: Executors.NewCachedThreadpool (New DäemonThreadfactory ()* können wir ein ThreadFactory -Objekt übergeben, sodass wir den Thread einstellen können, den wir als Hintergrund -Thread durch diese Methode beginnen möchten* Dies ist zu notiert. Thread (R); Schlaf, die Hauptlinie wird den Lauf beenden. (InterruptedException e) {System.out.println ("Interrupted");}} öffentliche statische void main (String [] args) {ExecutorService exec = ausführende Daemonfromfactory ());} System.out.println ("Alle Dameons gestartet"); try {timeUnit.milliseconds.sleep (500);} catch (InterruptedException E) {E.printstacktrace ();}}}}}}}}}}}}}}}}}}}}}}}}}}}}}Das endgültige Ausgangsergebnis ist:
Alle Dameons begannen
Thread [Thread-3,5, Main] Concurrency.daemonfromfactory@56214c1
Thread [Thread-2,5, Main] Concurrency.daemonfromfactory@5724147d
Thread [Thread-0,5, Main] Concurrency.daemonfromfactory@144Fe080
Thread [Thread-1,5, Main] Concurrency.daemonfromfactory@104fa29e
Thread [Thread-8,5, Main] Concurrency.daemonfromfactory@5b069a7f
Thread [Thread-9,5, Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-7,5, Main] Concurrency.daemonfromfactory@25144c3e
Thread [Thread-4,5, Main] Concurrency.daemonfromfactory@288523d
Thread [Thread-6,5, Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-5,5, Main] Concurrency.daemonfromfactory@626007aa
Thread [Thread-3,5, Main] Concurrency.daemonfromfactory@56214c1
Thread [Thread-2,5, Main] Concurrency.daemonfromfactory@5724147d
Thread [Thread-6,5, Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-5,5, Main] Concurrency.daemonfromfactory@626007aa
Thread [Thread-4,5, Main] Concurrency.daemonfromfactory@288523d
Thread [Thread-9,5, Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-7,5, Main] Concurrency.daemonfromfactory@25144c3e
Thread [Thread-8,5, Main] Concurrency.daemonfromfactory@5b069a7f
Thread [Thread-1,5, Main] Concurrency.daemonfromfactory@104fa29e
Thread [Thread-0,5, Main] Concurrency.daemonfromfactory@144Fe080
Thread [Thread-2,5, Main] Concurrency.daemonfromfactory@5724147d
Thread [Thread-3,5, Main] Concurrency.daemonfromfactory@56214c1
Thread [Thread-6,5, Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-1,5, Main] Concurrency.daemonfromfactory@104fa29e
Thread [Thread-0,5, Main] Concurrency.daemonfromfactory@144Fe080
Thread [Thread-7,5, Main] Concurrency.daemonfromfactory@25144c3e
Thread [Thread-8,5, Main] Concurrency.daemonfromfactory@5b069a7f
Thread [Thread-5,5, Main] Concurrency.daemonfromfactory@626007aa
Thread [Thread-9,5, Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-4,5, Main] Concurrency.daemonfromfactory@288523d
Thread [Thread-2,5, Main] Concurrency.daemonfromfactory@5724147d
Thread [Thread-3,5, Main] Concurrency.daemonfromfactory@56214c1
Thread [Thread-8,5, Main] Concurrency.daemonfromfactory@5b069a7f
Thread [Thread-7,5, Main] Concurrency.daemonfromfactory@25144c3e
Thread [Thread-4,5, Main] Concurrency.daemonfromfactory@288523d
Thread [Thread-6,5, Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-1,5, Main] Concurrency.daemonfromfactory@104fa29e
Thread [Thread-0,5, Main] Concurrency.daemonfromfactory@144Fe080
Thread [Thread-9,5, Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-5,5, Main] Concurrency.daemonfromfactory@626007aa
Thread [Thread-3,5, Main] Concurrency.daemonfromfactory@56214c1
Thread [Thread-2,5, Main] Concurrency.daemonfromfactory@5724147d
Thread [Thread-8,5, Main] Concurrency.daemonfromfactory@5b069a7f
4. Erstens sollten Sie erkennen, dass der Hintergrund -Thread, wenn der Benutzer -Thread plötzlich beendet ist, seine Auslaufmethode beendet, ohne die schließlich die Klausel auszuführen.
/* Wenn Sie dieses Programm anrufen, werden Sie feststellen, dass die endgültige Klausel nicht ausgeführt wird. Wenn Sie jedoch den Anruf von setdaemon () kommentieren, werden Sie feststellen, dass die* schließlich die Klausel ausgeführt wird.* Dieses Verhalten ist korrekt. Auch wenn Sie dieses Verhalten nicht auf dem Versprechen basieren, das Sie schließlich vor Ihnen gegeben haben. Aber das ist der Fall. Wenn der letzte Nicht-Background-Faden endet, stoppt der Hintergrundfaden plötzlich. Denn sobald main () beendet ist, schließt der JVM sofort alle * Threads im Hintergrund. Da Sie Hintergrund -Threads nicht auf elegante Weise schließen können, sind sie kaum eine gute Idee. Nicht-Backend-Manager sind in der Regel ein besserer Weg, da alle vom Ausführenden kontrollierten Aufgaben gleichzeitig geschlossen werden können. */class adaemon implementiert runnable {@Override public void run () {System.out.println ("adaemon starten"); Versuchen Sie {TimeUnit.Seconds.sleep (1); } catch (InterruptedException e) {System.out.println ("über InterruptedException"); } endlich {System.out.println ("das sollte immer ausgeführt werden?"); }}} öffentliche Klasse DaemonsDonTrunfinally {public static void main (String [] args) {Thread t = neuer Thread (new adaemon ()); T.Setdaemon (wahr); t.start (); }} Die endgültigen Ausgabeergebnisse sind wie folgt:
Adaemon starten
Wenn die Situation jedoch zur folgenden Situation wird, unterscheiden sich die Ausgabeergebnisse erneut:
Klasse adaemon implementiert runnable {@Override public void run () {System.out.println ("adaemon starten"); Versuchen Sie {TimeUnit.Seconds.sleep (1); } catch (InterruptedException e) {System.out.println ("über InterruptedException"); } endlich {System.out.println ("das sollte immer ausgeführt werden?"); }}} öffentliche Klasse DaemonsDonTrunfinally {public static void main (String [] args) {Thread t = neuer Thread (new adaemon ()); T.Setdaemon (wahr); t.start (); Versuchen Sie {TimeUnit.Seconds.sleep (1); } catch (interruptedException e) {e.printstacktrace (); }}}Da der Hauptfaden nicht plötzlich beendet, erhält der Hintergrund -Thread die Ausführungszeit während des Hauptfadens, sodass das endgültige Druckergebnis lautet:
Adaemon starten
Das sollte immer laufen?
Das obige ist der gesamte Inhalt dieses Artikels über die Analyse von Hintergrund -Thread -Instanzen in Java, und ich hoffe, dass es für alle hilfreich sein wird. Interessierte Freunde können weiterhin auf andere verwandte Themen auf dieser Website verweisen. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!