Wann sollte ich StringBuilder oder StringBuffer verwenden?

13

In einer Produktionswebanwendung verwendeten meine Programmierkollegen überall StringBuffer. Jetzt kümmere ich mich um die Anwendungsentwicklung und Korrekturen. Nach dem Lesen von StringBuilder und StringBuffer habe ich beschlossen, den gesamten StringBuffer-Code durch StringBuilder zu ersetzen, da in unseren Data Beans keine Threadsicherheit erforderlich ist.

Zum Beispiel: (In jeder Datenbohne kann ich die Verwendung von StringBuffer sehen)

@Override
public String toString() {
    StringBuffer sb = new StringBuffer();// replace it from StringBuilder
    sb.append(" ABCD : ").append(abcd);
    sb.append(", EFGH : ").append(efgh);
    sb.append(", IJKL : ").append(ijkl);
}

Wir erstellen für jede Sitzung / Anfrage ein eigenes Data Bean. Eine Sitzung wird von einem einzelnen Benutzer verwendet, auf den kein anderer Benutzer zugreifen kann.

Sollte ich vor der Migration andere Punkte berücksichtigen?

Wenn es einen einzelnen Thread gibt (keine wartenden Threads / kein neuer Thread sucht nach einer Objektsperre), wird die gleiche Leistung wie bei StringBuffer oder StringBuilder erzielt. Ich weiß, dass es im Fall von StringBuffer einige Zeit dauert, bis die Objektsperre aktiviert ist, aber ich möchte wissen, ob es Leistungsunterschiede zwischen ihnen gibt, mit Ausnahme des Haltens / Aufhebens der Objektsperre.

Satish Pandey
quelle
9
Wenn Sie sbwie in Ihrem Beispiel eine lokale Variable verwenden, spielt die Thread-Sicherheit keine Rolle. Selbst wenn tausend Threads gleichzeitig in die Methode eingingen, hätte jeder einen eigenen Aufrufstapel mit eigenen lokalen Variablen. Die StringBuilder würden sich niemals gegenseitig stören.
Fredoverflow
Ich habe mich immer gefragt, wer zwei Threads entlang der Schnittstelle eines synchronisieren möchte StringBuffer. Ich habe noch nie so einen Code gesehen, aber ich bin mir fast sicher, dass es sich aus Multithreading-Sicht um ein schlechtes Design handelt. Da ich denke, dass das Synchronisieren von Threads entlang der StringBufferSchnittstelle eine schlechte Idee ist, denke ich, dass diese Klasse nicht existieren sollte und man sie immer verwenden sollte StringBuilder. Wie bereits erwähnt, StringBufferbesteht aus historischen Gründen.
Pasztorpisti

Antworten:

22

Der einzige Unterschied zwischen den beiden ist die in StringBuffer verwendete Synchronisation. Der Aufwand für die Synchronisation ist im großen Rahmen der Dinge nicht groß, aber im Vergleich zu den StringBuilder-Methoden, die sie nicht haben, erheblich. Die JVM erledigt Arbeiten, die sie sonst nicht erledigen müsste - insbesondere mit nur einem Thread usw.

Wenn Ihr Code funktioniert und die Leute sich nicht über die Leistung beschweren, würde ich mir darüber keine Sorgen machen. Sie werden nicht viel für Ihr Geld bekommen. Wenn Sie jedoch neuen Code schreiben oder Code aktualisieren, der StringBuffer verwendet, empfiehlt es sich, diese gleichzeitig in StringBuilder zu konvertieren.

Matthew Flynn
quelle
Ich füge hinzu, dass Sie die Threadsicherheit der beiden im Hinterkopf behalten müssen. StringBuilder ist nicht threadsicher.
Martijn Verburg
2
@MartijnVerburg Richtig, obwohl in stackoverflow.com/questions/6775016/stringbuffer-is-obsolete/… darauf hingewiesen wurde, dass es nur sehr wenige Anwendungsfälle gibt, bei denen mehrere Threads dieselbe Instanz eines Stringbuilders verwenden müssen.
Matthew Flynn
4
@MartijnVerburg: es sollte auch beachtet werden: wenn du wirklich Thread-Sicherheit brauchst, StringBufferist das wahrscheinlich auch nicht ausreichend! Es garantiert, dass es nicht bremst, aber die Position, an der Sie anhängen, kann nicht einfach gesteuert werden, wenn mehrere Threads gleichzeitig darauf zugreifen, sodass eine weitere externe Synchronisierung erforderlich wäre.
Joachim Sauer
8

StringBuilder wurde zu einem Zeitpunkt hinzugefügt (Java 1.5), um ein besserer und schnellerer StringBuffer zu sein, und der Compiler verwendet ihn unter der Haube, um den +Operator auf Strings zu implementieren .

Dies bedeutet, dass Sie mit StringBuilder Ihren Code nicht älter als zum Zeitpunkt der Einführung der Klasse auf JVMs ausführen können. Dies wäre für uns noch eine Weile ein Problem. Wenn Sie immer auf dem neuesten Stand sind, brauchen Sie sich nicht darum zu kümmern.

Ich würde den Optimierungsprozess, den Sie durchlaufen, aus den folgenden Gründen nicht durchlaufen.

  • Außerhalb enger Schleifen ist der Vorteil vernachlässigbar. Wenn es nicht explizit als Hotspot in einem Profiler angezeigt wird, würde ich mich nicht darum kümmern.
  • Das Ändern des Codes kann zu Fehlern führen, und Sie müssen Ihre Anwendung erneut gründlich testen. Das kann viel teurer sein, als mit einer synchronisierten Klasse in einer nicht synchronisierten Umgebung zu leben.
Frank Shearar
quelle
Ich stimme Ihnen zu .. immer noch nicht in der Lage, Ihren Standpunkt zu verstehenOutside tight loops the advantage is negligible...
Satish Pandey
Der Mechanismus, der in StringBuilder im Gegensatz zu StringBuffer fehlt, ist die Handelsgeschwindigkeit für die Thread-Sicherheit. Das Geschwindigkeitsverbesserung ist sehr klein, so dass es wichtig ist nur , wenn es ein getan wird viel Mal - das ist in der Regel der Fall in einer kleinen Schleife viele Male getan.