2011-01-02 23 views
5

Kennt jemand die Auswirkungen der Sperrung in Java speziell auf die Geschwindigkeit der Ausführung des Programms? Wenn überhaupt, wie überwinden wir diesen Effekt? konkrete Referenzen sind willkommen ..Locking-Effekte in Java

+0

"Verlangsamungen" mit Sperren (unabhängig von der Synchronisierungsmethode) hängen vom Umfang der Konkurrenz ab. 1) Vermeiden Sie die Überbenutzung von Threads und "synchronisieren Sie alles" - die Parallelität mit Threading braucht Zeit zum Nachdenken 2) Benchmark * Ihre speziellen Fälle * 3) Betrachten Sie alternative Algorithmen Ansätze (zB Locks/Shared State reduzieren) 4) * Just don mach dir keine Sorgen * :-) –

Antwort

4

Wenn Ihre Anwendung hauptsächlich single-threaded ist, sehen Sie möglicherweise keine oder nur sehr geringe Leistungseinbußen, wenn Sie zu viel sperren.

Im Allgemeinen kann eine einzelne Sperre sehr schnell und effizient abgerufen werden, wenn die java.concurrent-Bibliotheken oder das integrierte synchronisierte Schlüsselwort verwendet werden. Sie verwenden Techniken wie Lock elision, adaptive locking und lock groensing (siehe Synchronization optimizations in Mustang), was im Grunde bedeutet, dass der Compiler und/oder die Bibliothek einige sehr kluge Dinge tun, um die Lock-Nutzung zu optimieren.

Dies spielt sich besonders in Situationen ab, in denen das Schloss nicht wirklich benötigt wird; der Compiler optimiert es weg.

Wenn jedoch eine Menge von Threads die gleichen Sperren greifen müssen, werden Sie schließlich feststellen, dass die CPU-Auslastung Ihrer Kerne nie 100% für ein reines Berechnungsproblem erreichen wird. In der Tat läuft etwas nicht so schnell wie es möglich ist, und Ihre CPU ist gerade im Leerlauf.

In Abwesenheit von (schweren) IO ist dies oft ein Zeichen von übermäßigen lock contention und dies beeinträchtigt somit die gesamte Systemleistung.

+0

dieser Artikel war, was ich suchte. Vielen Dank! – OckhamsRazor

1

Ich stimme @pst zu und möchte hinzufügen, dass, obwohl sie sagen, dass die Synchronisierung die Leistung reduziert, ich diese Effekte in meinen Tests nicht gesehen habe. Ich versuchte zu messen, wie diese Reduktion funktioniert und sah, dass dies fast nicht existiert. Wahrscheinlich war dieser Effekt in früheren Java-Tagen relevanter.

Beispiel für Versuche zur Vermeidung zusätzlicher Synchronisation ist eine Implementierung der Methode getInstance() im Singleton-Muster. Der einfachste Weg besteht darin, diese Methode zu synchronisieren, die (wahrscheinlich) zu Leistungseinbußen führt. Der nächste Schritt (der nicht funktioniert) ist eine Doppelprüfung. Und schließlich ist es die bessere Lösung, die Referenz auf die Instanz in die innere Klasse zu geben.

+0

danke für deine Hilfe! – OckhamsRazor

+0

fyi, dcl funktioniert tatsächlich, wenn Sie eine flüchtige Instanz verwenden. aber das Idiom "Initialize on Demand Holder", das Sie beschreiben, ist absolut besser und schneller für die Lazy-Initialisierung als dcl oder Synchronisation. –

2

Hier sind die nützlichen Links Runtime performance optimizations und Synchronization performance tips und Java synchronization and performance in an aspect in SO.

Wenn Sie Multithread-Programmierung schreiben, verwenden Sie java.util.concurrent Paket anstelle von wait() notify() sleep() stop() Old-Fashion-Ansätze.

Parallelität ist wirklich Kritiker Thema, das Sie nicht sagen können, wie es die Geschwindigkeit der Ausführung beeinflusst. Wenn es richtig ausgeführt wird, ist es gut, wenn nicht,

+0

danke für deine hilfe! – OckhamsRazor

3

Die Kosten für das Sperren variieren mit verschiedenen Java-Versionen. Für Java < = 1.4 war das Sperren relativ teuer. Allerdings wurde für Java 5.0 das eingebaute Locking verbessert, aber das neue gleichzeitige Locking war wieder schneller. In Java 6 sind beide ungefähr so ​​schnell wie jeder andere.

Als Anhaltspunkt können Sie die Kosten der Verriegelung erwarten eine Sperre zwischen 0,5 und 2,0 Mikrosekunden auf Java sein 6.

Perform kann teuer sein, da es einen Aufruf an das zugrunde liegende Betriebssystem einzubeziehen. (Auf virtualisierten Maschinen teurer) Eine Möglichkeit, dies zu vermeiden, ist die Verwendung der CAS-Operation mit einer Speicherbarriere.

Die einfachste/beste Möglichkeit, die Kosten für das Sperren zu reduzieren, besteht jedoch darin, Ihr Programm so zu strukturieren, dass Threads für längere Zeiträume ausgeführt werden können, ohne voneinander abhängig zu sein.

Sie könnten diesen Link interessant finden, wenn sie über das Sperren in einem in Java geschriebenen Handelssystem mit hohem Durchsatz sprechen. http://www.infoq.com/presentations/LMAX

+0

sehr guter link. Danke! – OckhamsRazor

1

Sperren (oder formaler, Serialisierung jeder Art) in jedem Algorithmus begrenzt seine Skalierbarkeit in einer Multi-CPU/Multi-Maschine-Umgebung. Amdahl's Law beschreibt es am besten.

Locking obwohl wird in der Praxis (in Java) vernachlässigbare Overhead auf einem rein sequentiellen Programm haben. Wie an anderer Stelle beschrieben, treten Leistungsprobleme nur bei Konflikten auf.