Der Titel lautet wie folgt:
public class testSync2 implementiert runnable {int b = 100; Synchronisierte void M1 () löst unterbrochene Ausnahme {b = 1000; Thread.Sleep (500); // 6 system.out.println ("b =" + b); } synchronisierte void M2 () löst unterbrochene Ausnahme {thread.sleep (250) aus; // 5 B = 2000; } public static void main (String [] args) löst unterbrochene {Testsync2 tt = new Testsync2 () aus; Thread t = neuer Thread (TT); // 1 t.start (); // 2 tt.m2 (); // 3 system.out.println ("Haupt Thread b =" + tt.b); // 4} @Override public void run () {try {m1 (); } catch (interruptedException e) {e.printstacktrace (); }}}Das Ausgabeergebnis dieses Programms?
Programmausgabeergebnisse
Hauptfaden B = 2000b = 1000
oder
Hauptfaden B = 1000b = 1000
Überprüfen Sie die Wissenspunkte
In Java sind Multi-Thread-Programme am schwierigsten zu verstehen und zu debuggen. Oft werden die Ausführungsergebnisse nicht wie wir uns vorgestellt. Daher ist es sehr schwierig, in Java Multi-Thread zu machen. Ich erinnere mich vage daran, als ich die C -Sprachstufe 2 im College einnahm, was ist die Frage in ++ und viele andere Prioritätsstufen entsprechen den endgültigen Ausgabeergebnissen. Ich möchte einige Prioritäts- und Kombinationsfragen für Läufer für diese Art von Frage stellen. Rezitieren Sie es einfach, indem Sie es sichern, aber Java Multi-Threading muss noch gut verstanden werden, Rückenlehne kann nicht getan werden.
Beginnen wir eine kurze Analyse:
Diese Frage umfasst 2 Threads (Haupt -Thread -Hauptfaden, untergeordnetes Thread), und die Schlüsselwörter beinhalten synchronisiert und thread.sleep.
Das synchronisierte Schlüsselwort ist immer noch ziemlich kompliziert (manchmal verstehe ich es nicht gut, daher hat die obige Frage einige Missverständnisse). Seine Funktion ist es, die Thread-Synchronisation zu realisieren (es gibt viele Methoden zur Implementierung der Thread-Synchronisation. Es handelt sich nur um eine Art andere Dinge, über die Follow-up-Artikel sprechen werden. Einige Implementierungen des Master Doug Lea müssen sorgfältig untersucht werden). Seine Aufgabe ist es, den Code zu sperren, der eine Synchronisation benötigt, damit nur ein Thread den Synchronisationsblock gleichzeitig eingeben kann (tatsächlich ist es eine pessimistische Strategie), um sicherzustellen, dass der Thread nur die Sicherheit erinnert.
Die Verwendung von allgemeinem Keyword synchronisiert
Im obigen Code gehört die Verwendung von Synchronisierten tatsächlich zum zweiten Fall. Direkt auf die Instanzmethode einwirken: Es ist gleichbedeutend mit der Verriegelung der aktuellen Instanz. Bevor Sie den Synchronisationscode eingeben, müssen Sie die Sperre der aktuellen Instanz erhalten.
Mögliche Missverständnisse
1. Da wir synchron nicht verstehen, betreiben wir eine synchronisierte Methode durch Multi-Threading. Wenn zwei Threads 2 verschiedene synchronisierte Methoden aufrufen, wird angenommen, dass es irrelevant ist. Diese Idee ist ein Missverständnis. Direkt auf die Instanzmethode einwirken: Es ist gleichbedeutend mit der Verriegelung der aktuellen Instanz. Bevor Sie den Synchronisationscode eingeben, müssen Sie die Sperre der aktuellen Instanz erhalten.
2. Wenn eine synchronisierte Methode aufgerufen wird. Ein weiterer Aufruf einer normalen Methode hat nichts zu tun, und die beiden haben keine Wartebeziehung.
Diese sind sehr nützlich für die nachfolgende Analyse.
Thread.sleep
Safess Der aktuelle Thread (d. H. Der Thread, der die Methode aufruft) für einen bestimmten Zeitraum und gibt anderen Threads die Möglichkeit, die Ausführung fortzusetzen, die Objektschloss jedoch nicht freigibt. Das heißt, wenn die synchronisierte Synchronisation schnell ist, können andere Threads immer noch nicht auf gemeinsame Daten zugreifen. Beachten Sie, dass diese Methode Ausnahmen erfassen muss, was für die anschließende Analyse sehr nützlich ist.
Analyseprozess
Java wird aus der Hauptmethode ausgeführt. Es wird gesagt, dass es 2 Threads gibt, aber selbst wenn Sie die Thread -Priorität hier ändern, ist es nutzlos. Die Priorität ist nur dann, wenn die beiden Programme noch nicht ausgeführt wurden. Nachdem dieser Code ausgeführt wurde, wurde der Haupt -Thread ausgeführt. Für die Attributvariable int b = 100 wird es kein Sichtbarkeitsproblem geben, da synchronisiert wird (und es ist nicht erforderlich zu sagen, dass die volatile Deklaration verwendet wird), wenn Schritt 1 (Thread t = neuer Thread (TT); // 1) der Thread in neuem Zustand ist und noch nicht funktioniert. Wenn die 2 Schritte ausgeführt werden (T.Start (); // 2), wenn die Startmethode aufgerufen wird, wird der Thread tatsächlich gestartet und tritt in den Laufstatus ein. Der Runnable -Status bedeutet, dass er ausgeführt werden kann und alles fertig ist, aber er bedeutet nicht, dass er auf der CPU ausgeführt werden muss. Ob es eine echte Ausführung gibt, hängt von der Planung der Service -CPU ab. Wenn Sie die 3 Schritte ausführen, müssen Sie zuerst die Sperre erhalten (weil Start die native Methode aufrufen muss und alles fertig ist, nachdem die Verwendung abgeschlossen ist. Es bedeutet jedoch nicht, dass sie auf der CPU ausgeführt werden muss. Ob eine echte Ausführung von der Planung des Service -CPU abhängt, und dann wird die M1 -Methode bezeichnet. Tatsächlich spielt es keine Rolle, ob der Thread in den beiden synchronisierten Methoden der Fall ist, es hat wahrscheinlich Schwierigkeiten der Verwirrung. Wenn die 3 Schritte ausgeführt werden, ist der untergeordnete Thread tatsächlich bald fertig, aber da synchronisiert wird und als dasselbe Objekt fungiert, muss der untergeordnete Thread warten. Da die Ausführungsreihenfolge in der Hauptmethode nacheinander ausgeführt wird, muss sie abgeschlossen werden, nachdem Schritt 3 ausgeführt wurde, bevor der 4. Schritt erreicht werden kann. Da die Ausführung von Schritt 3 abgeschlossen ist, kann der untergeordnete Thread M1 ausführen. Hier gibt es ein Problem, wer das Multi-Thread zuerst bekommt. Wenn die 4 Schritte zuerst erhalten werden, dann ist Hauptfaden B = 2000. Wenn der untergeordnete Thread M1 erhalten wird, wurde B möglicherweise 1000 oder bevor die 4 Schritte zugeordnet sind, das mögliche Ergebnis ist Hauptgewinde B = 1000 oder Hauptfaden B = 2000. Wenn die 6 Schritte hier entfernt werden, ist B = vor und der Hauptfaden b = vor ungewiss. Da jedoch 6 Schritte vorhanden sind, egal was passiert, ist der Hauptfaden B = vorne, so dass es von der Situation abhängt, ob er 1000 oder 2000 entspricht. Danach ist B = 1000 definitiv festgelegt.
Einige Vorschläge für Multi-Threading
Es gibt auch einige Tipps, die Sie in den nachfolgenden Artikeln teilen können. Multi-Threading ist besonders wichtig und schwierig. Ich hoffe, dass jeder mehr Zeit damit verbringen wird.
Einige Debugging -Techniken für Multithreading
Aufgrund von Haltepunkten müssen alle Threads beim Durchlaufen von Haltepunkten aufhören, was dazu führt, dass dieser Punkt ständig unterbrochen wird, was sehr unangenehm ist. Es gibt bedingte Haltepunkte in Eclispe, und Sie können anhalten, wenn die Bedingungen erfüllt sind. Dies ist also bequem.
Zusammenfassen
Das oben genannte ist die schwierigste Frage des Java -Interviews in der Geschichte, die der Herausgeber Ihnen vorgestellt hat. Ich hoffe, es wird Ihnen hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Editor wird Ihnen rechtzeitig antworten. Vielen Dank für Ihre Unterstützung auf der Wulin.com -Website!