Viele Kernfragen von Java-Interviews stammen aus Multi-Threading- und Sammlungsrahmen. Kompetente praktische Erfahrung ist notwendig, wenn das Konzept von Kernfäden versteht. In diesem Artikel werden einige typische Fragen zum Java -Threading erfasst, die häufig von leitenden Ingenieuren gefragt werden.
0. Was ist Multi-Thread-Synchronisation in Java?
Bei Programmen mit Multi-Thread-Programmen kann die Synchronisation den Zugriff auf gemeinsam genutzte Ressourcen steuern. Wenn keine Synchronisation vorliegt und ein Java -Thread eine gemeinsam genutzte Variable ändert, wird ein anderer Thread dieselbe Variable verwendet oder aktualisiert, was leicht zu falschen Ergebnissen im Programm führen kann.
1. Erklären Sie verschiedene Möglichkeiten zur Implementierung von Multi-Threading?
Ein Java -Thread kann die Runnable -Schnittstelle implementieren oder die Thread -Klasse erben, um sie zu implementieren. Wenn Sie vorhaben, mehrmals zu erben, werden Sie es vorziehen, Runnable zu implementieren.
2. Was ist der Unterschied zwischen Thread.start () und thread.run ()?
Der Thread.Start () -Methode (nativ) startet den Thread und tritt in den Bereitschaftszustand ein. Wenn die CPU dem Thread Zeit zuteilt, plant die JVM, die Run () -Methode auszuführen.
3. Warum brauchen wir die Methoden run () und starten ()? Können wir einfach die Run () -Methode verwenden, um die Aufgabe zu erledigen?
Wir benötigen die beiden Methoden von Run () & start (), da das JVM einen separaten Thread erstellt als der Aufruf der normalen Methoden. Diese Arbeit erfolgt daher durch die Startmethode des Threads. Der Start wird nach der lokalen Methode implementiert und muss angezeigt werden. Ein weiterer Vorteil der Verwendung dieser beiden Methoden besteht darin, dass jedes Objekt als Thread ausgeführt werden kann. Solange die Runnable -Schnittstelle implementiert ist, vermeidet dies die multiplen Vererbungsprobleme von Java, die durch Erben der Thread -Klasse verursacht werden.
4. Was ist die ThreadLocal -Klasse und wie kann ich sie verwenden?
ThreadLocal ist eine lokale Variable auf Thread-Ebene, kein "lokaler Thread". ThreadLocal bietet eine unabhängige Kopie der Variablen für jeden Thread, der die Variable verwendet. Jeder Thread wirkt sich nicht auf die Kopie anderer Thread -Objekte aus, wenn die Kopie geändert wird (Anmerkung des Übersetzers).
Hier sind die wichtigsten Punkte von lokalen Variablen von Threads:
Eine lokale Thread -Variable (ThreadLocal Variable) bietet bequem eine separate Variable für jeden Thread.
Threadlokalinstanzen werden normalerweise in einer Klasse als statische private (private statische) Felder angezeigt, die zum Zusammenhang mit einem Thread verwendet werden.
Wenn mehrere Threads auf Threadlocal -Instanzen zugreifen, behält jeder Thread eine unabhängige Kopie der von ThreadLocal bereitgestellten Variablen bei.
Häufig verwendete Verwendungen sind im DAO -Modus zu sehen. Wenn es sich bei der DAO -Klasse um eine Singleton -Klasse handelt, wird die Datenbankverbindung von jedem Thread unabhängig voneinander geführt und wirkt sich nicht gegenseitig aus. (Singleton basierend auf Thread)
5. Wann wird der InvalidMonitorStateException geworfen und warum?
Wenn Sie eine der Methoden im Wait ()/notify ()/notifyall () aufrufen, wenn der aktuelle Thread die Sperre des Objekts nicht erhält, wird eine Ausnahme von IllegalMonitorStateException geworfen (dh, wenn das Programm keinen Synchronisierungsblock oder keine Synchronisierungsmethode des Objekts ausführt, versuchen Sie, Wait zu rufen (). Da es sich bei der Ausnahme um eine Unterklasse von RunTimeExcpetion handelt, muss die Ausnahme nicht gefangen werden (obwohl Sie sie so lange fangen können, wie Sie möchten). Als RunTimeException werden solche Ausnahmen in der Wait (), benachrichtigen (), meldenall () Methodensignatur nicht erwähnt.
6. Was ist der Unterschied zwischen Schlaf (), suspend () und wait ()?
Thread.sleep () macht den aktuellen Thread in einem "nicht laufbaren" Status zur angegebenen Zeit. Der Thread hält immer den Monitor des Objekts. Wenn sich beispielsweise ein Thread derzeit in einer Synchronisationsblock- oder Synchronisationsmethode befindet, können andere Threads den Block oder die Methode nicht eingeben. Wenn ein anderer Thread die Interrupt () -Methode aufruft, wird dieser "schlafende" Thread aufwacht.
Hinweis: Sleep () ist eine statische Methode. Dies bedeutet, dass es nur für den aktuellen Thread gültig ist, und ein gemeinsamer Fehler ist, T.Sleep () aufzurufen (hier ist t ein Thread, der sich vom aktuellen Thread unterscheidet). Auch wenn T.Sleep () ausgeführt wird, schläft der aktuelle Thread und nicht der T -Thread. T.Suspend () ist eine veraltete Methode. Durch die Verwendung von Suspend () geht der Thread in einen stagnierenden Zustand ein. Der Thread hält immer den Monitor des Objekts, und Suspend () verursacht wahrscheinlich Deckenprobleme.
Object.wait () lässt den aktuellen Thread aus einem "unringbaren" Zustand kommen. Im Gegensatz zu Sleep () ist Warten eher eine Objektmethode als eine Fadenmethode. Beim Aufrufen von Object.wait () muss der Thread zunächst die Objektsperrung dieses Objekts abrufen. Der aktuelle Thread muss das Sperrobjekt synchronisiert und den aktuellen Thread zur Warteschlange hinzufügen. Anschließend kann ein weiterer Thread die gleiche Objektsperrung synchronisieren, um Objekt zu aufrufen. Notify (), wodurch der ursprünglich gewartete Thread aufweckt und dann die Sperre losgelassen hat. Im Grunde genommen ist Wait ()/notify () ähnlich wie bei Sleep ()/Interrupt (), außer dass er erstere verlangt, dass das Objektschloss erworben werden muss.
7. Was passiert bei der Verwendung der Synchronisation bei statischen Methoden?
Bei der Synchronisierung einer statischen Methode wird das "Klasse" -Objekt der Klasse erhalten. Wenn ein Thread in eine synchronisierte statische Methode eingeht, erfasst der Thread -Monitor die Objektschloss der Klasse selbst, und andere Threads können keine statische Synchronisationsmethode dieser Klasse eingeben. Es ist nicht wie eine Instanzmethode, da mehrere Threads gleichzeitig synchronen Instanzmethoden auf verschiedene Instanzen zugreifen können.
8. Wenn eine Synchronisationsmethode ausgeführt wurde, kann der Thread die asynchrone Instanzmethode auf dem Objekt aufrufen?
Ja, eine asynchrone Methode kann immer ohne Probleme aufgerufen werden. Tatsächlich führt Java keine Überprüfungen für asynchrone Methoden durch, und Sperrobjekte werden nur in Synchronisationsmethoden oder Synchroncodeblöcken überprüft. Wenn eine Methode nicht als synchron deklariert wird, wird Java sie trotzdem anrufen, ohne zu überprüfen, ob sie sicher sind, ob sie sicher sind. Seien Sie also in diesem Fall besonders vorsichtig. Ob eine Methode synchron deklariert wird, hängt vom Zugang zum kritischen Abschnitt ab. Wenn die Methode nicht auf den kritischen Abschnitt (gemeinsame Ressourcen oder Datenstrukturen) zugreift, ist es nicht erforderlich, Synchron zu deklarieren.
Hier ist ein Beispiel: Gemeinsame Klasse hat zwei Methoden SynchronizedMethod1 () und Method1 (), und die MyThread -Klasse ruft diese beiden Methoden in einem unabhängigen Thread auf.
public class Common {public synchronisierte void synchronisierte Methode1 () {System.out.println ("SynchronizedMethod1 genannt"); try {thread.sleep (1000); } catch (interruptedException e) {e.printstacktrace (); } System.out.println ("SynchronizedMethod1 erledigt"); } public void method1 () {System.out.println ("Methode 1 genannt"); try {thread.sleep (1000); } catch (interruptedException e) {e.printstacktrace (); } System.out.println ("Methode 1 erledigt"); }} öffentliche Klasse MyThread erweitert Thread {private int id = 0; privates gemeinsames gemeinsames; public myThread (String -Name, int no, Common Object) {Super (Name); Common = Objekt; id = nein; } public void run () {System.out.println ("Thread" + this.getName ()); try {if (id == 0) {Common.ynchronizedMethod1 (); } else {Common.Method1 (); }} catch (Ausnahme e) {e.printstacktrace (); }} public static void main (String [] args) {gemeinsam c = new Common (); MyThread t1 = neues MyThread ("MyThread-1", 0, c); Mythead t2 = new MyThread ("MyThread-2", 1, c); t1.start (); t2.Start (); }}Hier ist die Ausgabe des Programms:
Ausführen von Threadmythread-1
Synchronisierte Method1 genannt
Ausführen von Threadmythread-2
Methode 1 aufgerufen
synchronisierte Methode1 erledigt
Methode 1 fertig
Die Ergebnisse zeigen, dass die method1 () aufgerufen wird, selbst wenn die synchronisierte Methode () ausgeführt wird.
9. Können zwei Threads zwei verschiedene Synchroninstanzmethoden auf einem Objekt aufrufen?
Nein, da ein Objekt die Instanzmethode synchronisiert hat, erfasst der Thread die Objektschloss des Objekts. Daher können andere Synchronisationsmethoden erst nach der Veröffentlichung der Methode ausgeführt werden, nachdem die Objektschloss freigegeben wurde. Das folgende Codebeispiel ist sehr klar: Die gemeinsame Klasse hat synchronisierte Methoden () und synchronisierte Methoden () synchronisierte Methoden und MyThread ruft diese beiden Methoden auf.
public class Common {public synchronisierte void synchronisierte Methode1 () {System.out.println ("SynchronizedMethod1 genannt"); try {thread.sleep (1000); } catch (interruptedException e) {e.printstacktrace (); } System.out.println ("SynchronizedMethod1 erledigt"); } public synchronisierte void synchronizedMethod2 () {System.out.println ("SynchronizedMethod2 CALLE"); try {thread.sleep (1000); } catch (interruptedException e) {e.printstacktrace (); } System.out.println ("SynchronizedMethod2 erledigt"); }} öffentliche Klasse MyThread erweitert Thread {private int id = 0; privates gemeinsames gemeinsames; public myThread (String -Name, int no, Common Object) {Super (Name); Common = Objekt; id = nein; } public void run () {System.out.println ("Thread" + this.getName ()); try {if (id == 0) {Common.ynchronizedMethod1 (); } else {Common.ynchronizedMethod2 (); }} catch (Ausnahme e) {e.printstacktrace (); }} public static void main (String [] args) {gemeinsam c = new Common (); MyThread t1 = neues MyThread ("MyThread-1", 0, c); Mythead t2 = new MyThread ("MyThread-2", 1, c); t1.start (); t2.Start (); }}10. Was ist ein Deadlock
Ein Deadlock bedeutet, dass zwei oder mehr Fäden unendlich blockiert sind und Fäden aufeinander aufeinander warten, um die erforderlichen Ressourcen zu erhalten. Dies kann passieren, wenn zwei Threads versuchen, Sperren für andere Ressourcen zu erwerben, und jeder Thread wartet auf unbestimmte Zeit auf die Freigabe anderer Ressourcensperrungen, es sei denn, ein Benutzerprozess wird beendet. In Bezug auf Javaapi können in der folgenden Situation Thread -Deadlocks auftreten.
11. Was hungert ein Faden und was ist ein lebendes Schloss?
Obwohl Fadenverhungern und Lebenssperrungen nicht als häufige Probleme wie Deadlocks angesehen werden, sind sie wie eine Begegnung für Designer der gleichzeitigen Programmierung.
Wenn alle Threads blockiert sind oder nicht verarbeitet werden können, da die erforderliche Ressource ungültig ist, gibt es keine nicht blockierenden Threads, die die Ressource verfügbar machen. Thread Live -Schlösser in Javaapi können in den folgenden Situationen auftreten:
Die Fragen hier sind nicht detailliert, ich hoffe, sie werden für alle hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Editor wird allen rechtzeitig antworten. Vielen Dank für Ihre Unterstützung auf der Wulin.com -Website!