Frage

Ich bin wirklich neu in Java und ich las, dass synchronized „sehr teuer“ in Java. Alles, was ich wissen will, ist, was teuer ist und wie ist es teuer?

Danke.

War es hilfreich?

Lösung

Vielleicht ist es nicht so schlimm, wie Sie denken,

Es wird verwendet, schrecklich zu sein (was möglicherweise ist, warum Sie lesen, dass es „sehr teuer“ war). Diese Meme kann eine lange Zeit dauern, bis aussterben

  

Wie teuer ist die Synchronisation?

     

Aufgrund der Regelungen, die Cache-Spülung und die Entwertung, ein synchronisierten Block in der Java-Sprache im Allgemeinen teurer als die kritischen Abschnitts Einrichtung ist von vielen Plattformen angeboten, die in der Regel mit einem Atom umgesetzt werden „Test und Bit gesetzt“ Maschinenbefehl. Selbst wenn ein Programm nur einen einzigen Thread enthält, auf einem einzigen Prozessor ausgeführt wird, ist eine synchronisierte Methodenaufruf immer noch langsamer als eine unsynchronisierte Methodenaufruf. Wenn die Synchronisation für die Sperre erfordert streit tatsächlich ist die Leistungseinbuße wesentlich größer ist, als es erforderlich mehrere Threadwechsel und Systemaufrufe werden.

     

Zum Glück, kontinuierliche Verbesserungen in der JVM haben sowohl insgesamt als Java-Programm eine verbesserte Leistung und reduzierten die relativ Kosten der Synchronisation mit jedem Release und zukünftige Verbesserungen zu erwarten sind. Ferner sind die Leistungskosten der Synchronisation oft genug betont. Eine bekannte Quelle hat zitiert, dass ein synchronisierter Methodenaufruf ist, so viel wie 50-mal langsamer als ein unsynchronisierte Methodenaufruf. Während diese Aussage wahr sein kann, ist es auch ziemlich irreführend ist und hat viele Entwickler nicht synchronisiert werden, auch in Fällen, in denen es erforderlich ist.

geführt

Nachdem das nun gesagt, dass - die gleichzeitige Programmierung noch langsam sein kann, aber nicht so viel davon jetzt rein Java Schuld ist. Es gibt einen Kompromiss zwischen feiner und grober Verriegelung. Zu grob ist natürlich schlecht, aber es ist möglich, auch in Ordnung zu sein, da Sperren ein nicht Null-Kosten haben.

Es ist wichtig, die bestimmte Ressource unter Behauptung zu prüfen. Mechanische Festplatten sind ein Beispiel, wo mehr Threads zu führen kann schlimmer Leistung.

Andere Tipps

Es ist teuer, denn wenn Sie Threads verwenden, und eine Anzahl von Threads durch einen synchronisierten Codeabschnitt gehen, nur einer von ihnen kann zu einem Zeitpunkt ausgeführt werden.

Es ist wie ein Engpass.

Es ist auch teuer, wenn Sie einen einzelnen Thread verwendet werden, da es ohnehin zu prüfen hat, ob er ausgeführt werden darf.

Wenn Sie die Verwendung von synchronisierten Segmenten Thread reduzieren wird nicht aufhören, um zu sehen, ob sie laufen können (natürlich müssen sie Daten nicht teilen)

Ein hohes Maß Überblick darüber, wie die Synchronisation funktioniert gefunden werden können

http://img20.imageshack.us/img20/2066/monitor28synchronizatioc.png

Ein Java-Stil-Monitor

Dies ist nicht spezifisch für Java. Die Synchronisation kann „teuer“ in jeder Multi-Threaded-Umgebung in Betracht gezogen werden, wenn nicht richtig gemacht. Ob es besonders schlimm in Java, ich weiß es nicht.

Es verhindert, dass Threads gleichzeitig ausgeführt werden, wenn sie die gleiche Ressource verwenden. Aber, da sie tun verwendet die gleiche Ressource, gibt es keine bessere Option (es muss getan werden).

Das Problem ist, dass die Menschen oft eine Ressource mit einem zu großem Umfang schützen. Zum Beispiel kann ein schlecht konzipiertes Programm ein ganzes Array von Objekten synchronisieren anstatt jedes einzelnen Elemente in dem Array (oder sogar einen Teil des Arrays).

Dies würde bedeuten, dass ein Fadenelement 7 zu lesen versucht, für einen Thread lesen warten muss oder Schreibelement 22 nicht erforderlich. Wenn die Granularität der Synchronisation auf Elementebene anstelle der Array-Ebene, würden diese beiden Fäden nicht miteinander interferieren.

Nur wenn zwei Threads der gleiche -Element würde es Ressourcenkonflikte zuzugreifen versucht. Deshalb ist die allgemeine Regel nur als klein, um eine Ressource wie möglich zu schützen (vorbehaltlich der Beschränkungen von der Anzahl der Synchronisationen, natürlich).

Aber, um ehrlich zu sein, es ist egal, wie teuer es ist, wenn die alternative Datenbeschädigung aufgrund von zwei Threads über eine einzige Ressource zu kämpfen. Schreiben Sie Ihre Anwendung korrekt und nur über Performance-Probleme kümmern, ob und wann sie erscheinen ( „Get it ersten Arbeits und es schnell bekommen arbeiten“ ein beliebtes Mantra von mir ist).

Die Artikel über IBM fasst eigentlich sehr schön die wichtigsten Punkte hinter Synchronisation.

  

Aufgrund der Regelungen, die Cache-Spülung und die Entwertung, ein synchronisierten Block in der Java-Sprache im Allgemeinen teurer als die kritischen Abschnitts Einrichtung ist von vielen Plattformen angeboten, die in der Regel mit einem Atom umgesetzt werden „Test und Bit gesetzt“ Maschinenbefehl. Selbst wenn ein Programm nur einen einzigen Thread enthält, auf einem einzigen Prozessor ausgeführt wird, ist eine synchronisierte Methodenaufruf immer noch langsamer als eine unsynchronisierte Methodenaufruf. Wenn die Synchronisation für die Sperre erfordert streit tatsächlich ist die Leistungseinbuße wesentlich größer ist, als es erforderlich mehrere Threadwechsel und Systemaufrufe werden.

Die anderen Antworten geben ein gutes Maß an technischen Details, die ich werde versuchen, nicht zu replizieren.

Was ich tun ist, beraten Sie die Termine des Artikels zu überprüfen (sowie die implizite Kompetenz und Bewusstsein des Autors). Synchronisation in Java war sehr langsam in früheren JVMs. Allerdings ist es in letzter Zeit viel verbessert, so dass uncontended Synchronisation viel schneller ist, als Sie vielleicht denken, und uncontended Synchronisation zu verbessern.

Wohlgemerkt, diese Frage möglicherweise spielt keine Rolle - wenn Sie Korrektheit sicherstellen müssen, synchronisieren, können Sie Notwendigkeit synchronisieren Richtigkeit sicherzustellen. Das einzige Mal, kann ich sehen, wobei die Geschwindigkeit ein Problem ist, wenn Sie stattdessen eine lockless Implementierung zu schaffen Berücksichtigung wurde (die sehr effizient, aber komplexen java.util.concurrent.locks.AbstractQueuedSynchronizer ), oder vielleicht erwägen stattdessen eine andere Sprache für Ihre Aufgabe verwendet wird.

Generell denke ich, die beste Schlussfolgerung ist, dass die Synchronisation der Regel schnell genug ist, auf einer ersten Iteration zu verwenden. Wie bei allen Performance betrifft, Code für Klarheit und Korrektheit auf den ersten und dann nur optimieren, was Sie messen ein teures Teil Ihrer Anwendung zu sein. Typischerweise wird dies nicht die Kosten für die Synchronisation *.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top