2010-12-04 12 views
10

In einem stark konkurrierenden Java-Programm und unter der Annahme, dass meine Methoden korrekt geschrieben sind und korrekt synchronisiert, ich frage mich, wie Sie feststellen, was besser ist:Kosten der Synchronisation

void synchronized something() { 
    ... 
} 

oder

void something() { 
    synchronized(this) { 
     ... 
    } 
    // here do stuff no requiring synchronization 
    . 
    . // do computation 'A' 
    . 
    synchronized(this) { 
     ... 
    } 
    // here do other stuff no requiring synchronization 
    . 
    . // do computation 'B' 
    . 
    synchronized(this) { 
     ... 
    } 
} 

Jetzt erkenne ich, dass, wenn die Berechnung von 'A' und 'B' viel Zeit in Anspruch nimmt, die zweite Version offensichtlich besser ist.

Meine Frage ist jedoch: An welchem ​​Punkt wissen Sie, dass die zweite Version effizienter ist?

Ist die zweite Version immer schneller oder gibt es versteckte Kosten, wenn Sie die Sperre mehrfach erfassen/freigeben?

Was passiert, wenn meine Berechnung 'A' ist einfach etwas trivial wie:

s.getString().substring(0, 2).toLowerCase(); 
+0

Beachten Sie, dass ich meine Kopie von * "Java Concurrency in der Praxis" * * habe – SyntaxT3rr0r

Antwort

8

Ja, kostet synchronized Zeit. Wenn die tatsächlichen Berechnungen einfach sind und es innerhalb einer Schleife oder so ist, kostet es Lose der Zeit im Vergleich zu den tatsächlichen Berechnungen.

dieses Beispiel Siehe: http://ideone.com/zgpB7

  • Innenteil synchronisiert: ca. 0.025s
  • Ganz Schleife synchronisiert: weniger als 0,001 s

zu bestimmen, welche für Ihr Programm besser ist, lassen es macht Sachen und schaut, zu welcher Zeit es schneller ist.

+0

+1 ... Ich bin ziemlich schockiert :) Ich war fast sicher, dass es mehr als das, was das Auge trifft :) – SyntaxT3rr0r

+5

Die andere Sache, die dieses Beispiel zeigt, ist, dass 1.000.000 Synchronisationssperren 0,024 Sekunden dauern. Wenn Sie also nicht millionenfach iterieren oder Sie einen provozierbaren Ressourcenkonflikt zwischen Threads haben, ist die Synchronisation selbst nicht so langsam. (scheinbar 0,000000024 sec pro Schloss auf welcher Maschine diese Beispiele lief). – Gus

+1

Ich denke, der größte Erfolg bei der Verwendung großer synchronisierter Blöcke ist der Verlust von Nebenläufigkeit. Plötzlich helfen deine multiplen Prozessoren nicht. Wenn Sie andere Threads haben, die nicht auf die Sperre warten, ist es möglicherweise nicht so schlecht – Cruncher

2

Thejh macht einen guten Punkt, dass es einige Kosten gibt, um einen Thread wiederholt zu sperren. Immer, wenn ich mit Leuten über parallele Threads gesprochen habe, ging es immer darum, sicherzustellen, dass alle Threads schnell ausgeführt werden, wenn sie gleichzeitig ausgeführt werden.

Wenn Sie eine Sperre länger als erforderlich beibehalten, können Sie die anderen Threads verlangsamen. Sie müssen sitzen und warten, während Sie arbeiten, die die Arbeit, die sie machen wollen, nicht stören. Wenn dies eine Situation ist, in der Ihnen Millisekunden wirklich wichtig sind, sollten Sie einen Profiler verwenden, um zu sehen, was in Ihrer Situation am besten funktioniert. Multi-Threading-Optimierung ist eine der Situationen, in denen es "Best Practices" gibt, die allgemein gelten, aber Sie werden keine Regel bekommen, die in allen Situationen funktioniert. Wenn Sie so viel Granularität benötigen, sollten Sie es testen und sehen.

1

Bedeutet "richtig geschrieben" und "korrekt synchronisiert", dass es im mehrsynchronisierten Fall keine Abhängigkeiten zwischen den Code-Abschnitten gibt? Wenn Abhängigkeiten vorhanden sind, könnte es sein, dass der mehrfach synchronisierte Fall zu einer Verletzung einer Invariante führen könnte. Anders gesagt, können Sie garantieren, dass die Ausführung des mehrfach synchronisierten Falls nicht dazu führt, dass sich ein Objekt in einem ungültigen Zustand befindet? Wenn nicht, dann könnte der einfach synchronisierte Fall besser sein.

+0

yup, es ist garantiert. Das ist genau die Prämisse meiner Frage :) IOW, du kannst meine Frage als eine rein theoretische Frage sehen :) – SyntaxT3rr0r

+1

@SpoonBender: In diesem Fall könnte die relative Leistung der beiden Lösungen von der Anzahl der verfügbaren CPU-s abhängen. –

+0

@SteveEmmerson oder eine Funktion des Verhältnisses zwischen Anzahl der Threads und CPUs. – Cruncher