Kursinhalt
Multithreading in Java
Multithreading in Java
Leistung und Herausforderungen
Leistungsbewertung
Sie können die Methoden nanoTime()
oder System.currentTimeMillis()
verwenden, um die Ausführungszeit von Multithread-Code zu messen.
Hinweis
In diesem Video vergleicht der Code die Leistung der multithreaded und single-threaded Summierung von Array-Elementen in Java. Es initialisiert ein Array mit zufälligen Ganzzahlen, verteilt die Aufgabe auf mehrere Threads, um die Summe parallel zu berechnen, und führt dann die gleiche Summierung sequentiell durch, um die Ausführungszeiten zu messen und zu vergleichen.
Datenrennen
Race-Bedingungen treten in multithreaded Programmen auf, wenn zwei oder mehr Threads gleichzeitig versuchen, auf eine gemeinsame Ressource ohne ordnungsgemäße Synchronisation zuzugreifen. Dies kann zu unvorhersehbarem und falschem Programmverhalten führen, da die Ergebnisse davon abhängen, wie Threads parallel ausgeführt werden und wie schnell sie auf die gemeinsame Ressource zugreifen.
Dieses Problem wurde im vorherigen Abschnitt besprochen, wo gezeigt wurde, wie das Problem mit dem synchronized
Schlüsselwort gelöst werden kann.
Unvorhersehbares Verhalten
Unvorhersehbares Verhalten kann durch unsachgemäße Synchronisation entstehen. Zum Beispiel kann das Fehlen von Synchronisation dazu führen, dass Threads mit veralteten Daten arbeiten.
In diesem Video zeigt der Code das Problem des unvorhersehbaren Verhaltens in Multithread-Anwendungen, das durch den Zugriff auf einen nicht synchronisierten gemeinsamen Zustand verursacht wird.
Entscheidung
Dieses Problem kann durch die Verwendung des
volatile
Schlüsselworts behoben werden. Eine alsvolatile
deklarierte Variable kann von mehreren Threads gleichzeitig geändert werden. Dies garantiert, dass der Wert der Variable nach der Änderung sofort für alle anderen Threads sichtbar ist.
Aber Sie müssen nicht alle Felder mit volatile deklarieren
Variablen, die als volatile
deklariert sind, werden bei jedem Lese- und Schreibzugriff mit dem Hauptspeicher synchronisiert. Das bedeutet, dass wenn ein Thread den Wert einer volatile
-Variablen aktualisiert, die Änderung sofort für alle anderen Threads sichtbar ist, was die Sichtbarkeit verbessert. Dies bedeutet jedoch auch, dass Lesevorgänge langsamer sein können, daher verwenden Sie volatile
nur, wenn es notwendig ist.
Deadlock
Deadlock tritt auf, wenn zwei oder mehr Threads in einer Warteschleife stecken bleiben, weil sie darauf warten, dass die jeweils anderen Ressourcen freigeben.
Im Video sind wir auf einen Deadlock gestoßen, als zwei Threads gleichzeitig die Monitore von Objekten in unterschiedlichen Sequenzen gesperrt haben, was zu einer Situation führte, in der die Threads einfach warteten, bis der jeweils andere die benötigten Monitore freigab.
Um dieses Problem zu lösen, müssen wir sicherstellen, dass solche Situationen nicht auftreten. Wir können dies erreichen, indem wir sicherstellen, dass alle Threads die Monitore von Objekten in der gleichen Reihenfolge sperren.
In diesem Fall wird der erste Thread, der den Monitor eines Objekts sperrt, andere Threads daran hindern, denselben Monitor zu sperren, und sie zwingen, zu warten, bis der erste Thread seine Aufgabe abgeschlossen hat. Erst nachdem der erste Thread fertig ist, wird er den Monitor freigeben, sodass andere Threads fortfahren können.
Vermeidung von Multithreading-Problemen
Daten-Synchronisation: Verwenden Sie das Schlüsselwort synchronized
für Methoden und Codeblöcke, um Datenrennen zu verhindern.
Vermeiden Sie gegenseitiges Sperren: Stellen Sie sicher, dass alle Threads Ressourcen in derselben Reihenfolge erwerben.
1. Welche Methode wird verwendet, um die Ausführungszeit von Code in Nanosekunden zu messen?
2. Wie nennt man das Problem, wenn mehrere Threads gleichzeitig versuchen, dieselbe Ressource zu ändern?
Danke für Ihr Feedback!