Wir haben jetzt die Top 3 des EJAPP Top 10 Countdowns erreicht, also legen wir los...
Falsch implementierte Gleichzeitigkeit kann die Leistung Ihrer Anwendung auf sehr unvorhersehbare Weise beeinträchtigen. Anwendungen, die bei geringer Belastung recht gut funktionieren, können bei höherer Belastung zum Stillstand kommen.
Sperrkonflikte können durch verschiedene Dinge verursacht werden:
- Synchronisierte Methoden und Blöcke, die sehr lange brauchen, um abgeschlossen zu werden. Siehe EJAPP Top 10 #6 - Unsachgemäßes Caching für ein Beispiel.
- Lang laufende Datenbanktransaktionen. Diese beeinträchtigen ebenfalls die Leistung, da sie große Mengen an Ressourcen wie Transaktionsprotokolle und Speicher verbrauchen.
- Lang laufende Datenbanktransaktionen mit hohen Isolationsstufen, die zu einer Eskalation der Sperren führen. Statt nur einer Zeile wird eine ganze Tabelle gesperrt, wodurch die Wahrscheinlichkeit steigt, dass mehrere Threads um dieselbe Sperre konkurrieren.
Während Sperrkonflikte nur dann ein Problem sind, wenn mehrere Threads beteiligt sind, fällt der mit der Verwaltung der Sperre verbundene Overhead auch dann an, wenn nur ein Thread beteiligt ist. Dies ist der Grund, warum Entwickler seit JDK 1.2 ArrayList gegenüber Vector und HashMap gegenüber Hashtable bevorzugen.
Genauso wie die Speicherverwaltung immer billiger geworden ist, hat sich die Leistung von Sperren in den letzten JDK-Versionen verbessert. JDK 1.6 enthält beispielsweise eine Reihe von Leistungsverbesserungen bei der Synchronisierung wie Lock Elision, Adaptive Locking und Lock Coarsening. Diese machen
- Minimieren Sie die Menge der Daten, auf die mehrere Threads zugreifen und die sie verändern müssen, und begrenzen Sie so die Anzahl der benötigten Sperren. Dazu gehören statische Variablen, Singletons, Datenbankzeilen usw.
- Wenn gemeinsam genutzte Daten geändert werden müssen, halten Sie den kritischen Abschnitt so kurz wie möglich.
- In Java sollten Sie es vermeiden, eigene Synchronisierungsprimitive zu schreiben. Verwenden Sie stattdessen java.util.concurrent (oder backport-util-concurrent).
- In der Datenbank sollten Sie die Verwendung einer optimistischen Gleichzeitigkeitssteuerung (von manchen verwirrend als optimistisches Sperren bezeichnet, obwohl es eigentlich nicht um Sperren geht) oder die Abschaffung von Transaktionen in Betracht ziehen.
- Und schließlich sollten Sie sich die Tipps zur Synchronisierungsleistung auf der Java Performance Tuning-Website ansehen.
Vielen Dank an Peter Veentjer für seinen wertvollen Beitrag zu diesem Blog.
Mehr aus dieser Serie
- EJApp Top 10 BOF-Sitzung auf der JavaPolis 2006
- #1: Falsche Verwendung der Datenbank
- #Nr. 2: Unnötiges Remoting
- #Nr. 3: Falsch implementierte Gleichzeitigkeit
- #Nr. 4: Schlecht funktionierende Bibliotheken
- #Nr. 5: Übermäßiger Speicherverbrauch
- #Nr. 6: Unsachgemäßes Caching
- #Nr. 7: Unnötige Verwendung von XML
- #Nr. 8: Falsche Verwendung von Java EE
- #9: Falsche Konfiguration des Anwendungsservers
- #Nr. 10: Exzessive Protokollierung
- EJApp Top 10 Countdown Nachbereitung
Verfasst von
Vincent Partington
Unsere Ideen
Weitere Blogs
Contact



