Unterschied zwischen StringBuilder und StringBuffer

1577

Was ist der Hauptunterschied zwischen StringBufferund StringBuilder? Gibt es Leistungsprobleme bei der Entscheidung für eines dieser Probleme?

schwarzer Tiger
quelle

Antworten:

1665

StringBufferist synchronisiert, StringBuilderist nicht.

sblundy
quelle
239
und StringBuilder ist als Ersatz für StringBuffer gedacht, wenn keine Synchronisation erforderlich ist
Joel
95
und eine Synchronisation ist praktisch nie erforderlich. Wenn jemand auf einem StringBuilder synchronisieren möchte, kann er einfach den gesamten Codeblock mit einem synchronisierten (sb) {} auf der Instanz umgeben
locka
23
@locka Ich würde argumentieren, dass StringBuffer nie eine gute Idee ist (es sei denn, Sie haben eine API, die es erfordert) vanillajava.blogspot.de/2013/04/…
Peter Lawrey
8
Der einzige Ort, den ich für einen StringBuffer sehe, ist die konsolenähnliche Ausgabe und verschiedene Protokollierungsdienstprogramme: Viele Threads können in Konflikten ausgegeben werden. Da Sie nicht möchten, dass 2 Ausgaben verwechselt werden ... aber normalerweise ist die Synchronisierung auf StringBuffer-Ebene zu niedrig, sollten Sie auf einem Appender wie levelm synchronisieren, damit die Antwort von locka die beste ist und StringBuffer veraltet sein sollte. Dies würde Code-Überprüfungszeit bei Neulingen sparen.
Remi Morin
20
Gute Mnemonik für diejenigen, die diese beiden mischen - BuFFer war First, ältere und daher synchronisierte Implementierung. Die neuere Builder-Klasse verwendet das Builder-Muster und ist asynchron.
Datageek
728

StringBuilderist schneller als StringBufferweil es nicht ist synchronized.

Hier ist ein einfacher Benchmark-Test:

public class Main {
    public static void main(String[] args) {
        int N = 77777777;
        long t;

        {
            StringBuffer sb = new StringBuffer();
            t = System.currentTimeMillis();
            for (int i = N; i --> 0 ;) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }

        {
            StringBuilder sb = new StringBuilder();
            t = System.currentTimeMillis();
            for (int i = N; i > 0 ; i--) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }
    }
}

Ein Testlauf gibt die Zahlen von 2241 msfor StringBuffervs 753 msfor an StringBuilder.

Polygenschmierstoffe
quelle
10
Ich habe das String-Literal in etwas Größeres geändert: "Der schnelle braune Fuchs" und habe interessantere Ergebnisse erzielt. Grundsätzlich sind sie ungefähr so ​​schnell. Mir ging tatsächlich der Speicher aus, so dass ich ein paar Siebenen entfernen musste. Erläuterung: Die Synchronisierung wird durch Hotspot optimiert. Sie messen im Grunde nur die Zeit, die Hotspot benötigt, um dies zu tun (und wahrscheinlich einige weitere Optimierungen).
Jilles van Gurp
7
Sie müssen sich vorher aufwärmen. Dieser Test ist gegenüber StringBuffer unfair. Es wäre auch gut, wenn es tatsächlich etwas anhängen würde. Eigentlich habe ich den Test umgedreht, eine zufällige Zeichenfolge angehängt und den entgegengesetzten Test erhalten. Man kann sagen, dass man einfachen Benchmarks nicht vertrauen kann. Das Gegenteil zeigt, dass StringBuffer schneller ist. 5164 für StringBuilder vs 3699 für StringBuffer hastebin.com/piwicifami.avrasm
mmm
75
Dies ist das erste Mal, dass ich --> 0in einer Schleife sehe . Ich brauchte einen Moment, um zu erkennen, was es bedeutet. Wird dies tatsächlich in der Praxis anstelle der üblichen ...; i > 0; i--Syntax verwendet?
Raimund Krämer
19
In i -->Bezug auf die Syntax ist das wirklich ärgerlich ... Ich dachte, es sei zunächst ein Pfeil, wegen der Kommentare zur ASCII-Kunst.
Sameer Puri
14
Andere schließen mit unterschiedlichen Ergebnissen: alblue.bandlem.com/2016/04/jmh-stringbuffer-stringbuilder.html . Benchmarks sollten wirklich mit JMH durchgeführt werden, nicht mit einem einfachen. main()Außerdem ist Ihr Benchmark unfair. Es gibt kein Aufwärmen.
Lukas Eder
249

Grundsätzlich werden StringBufferMethoden synchronisiert, während dies StringBuildernicht der Fall ist .

Die Operationen sind "fast" gleich, aber die Verwendung synchronisierter Methoden in einem einzelnen Thread ist übertrieben.

Das ist ziemlich viel.

Zitat aus der StringBuilder-API :

Diese Klasse [StringBuilder] bietet eine API, die mit StringBuffer kompatibel ist, jedoch keine Garantie für die Synchronisierung bietet . Diese Klasse ist als Drop-In-Ersatz für StringBuffer an Stellen vorgesehen, an denen der String-Puffer von einem einzelnen Thread verwendet wurde (wie dies im Allgemeinen der Fall ist). Nach Möglichkeit wird empfohlen, diese Klasse gegenüber StringBuffer zu verwenden, da sie bei den meisten Implementierungen schneller ist.

Also wurde es gemacht, um es zu ersetzen.

Das gleiche passierte mit Vectorund ArrayList.

OscarRyz
quelle
1
Auch mit Hashtableund HashMap.
Shmosel
176

Aber müssen Sie anhand eines Beispiels den klaren Unterschied feststellen?

StringBuffer oder StringBuilder

Verwenden StringBuilderSie es einfach, es sei denn, Sie versuchen wirklich, einen Puffer zwischen Threads zu teilen. StringBuilderist der nicht synchronisierte (weniger Overhead = effizienter) jüngere Bruder der ursprünglich synchronisierten StringBufferKlasse.

StringBufferkam zuerst. Sun war unter allen Bedingungen um Korrektheit bemüht, daher wurde es synchronisiert, um es für alle Fälle threadsicher zu machen.

StringBuilderkam später. Die meisten Verwendungszwecke StringBufferwaren Single-Thread- Anwendungen, bei denen die Kosten für die Synchronisierung unnötig bezahlt wurden.

Da StringBuilderist eine Drop-in - Ersatz für StringBuffer, ohne die Synchronisation würde es nicht zwischen irgendwelchen Beispielen Unterschiede geben.

Wenn Sie sich zu teilen zwischen Threads versuchen, können Sie verwenden StringBuffer, aber prüfen , ob übergeordnete Synchronisation erforderlich ist , zB vielleicht anstelle von String verwenden, sollten Sie die Methoden synchronisieren , die die Stringbuilder verwenden.

Bert F.
quelle
14
Die erste gute Antwort !! Der Punkt ist "es sei denn, Sie teilen einen Puffer zwischen Threads"
AlexWien
1
sehr detaillierte Antwort!
Raúl
81

Lassen Sie uns zunächst die Ähnlichkeiten sehen : Sowohl StringBuilder als auch StringBuffer sind veränderbar. Das heißt, Sie können den Inhalt an derselben Stelle ändern.

Unterschiede : StringBuffer ist auch veränderbar und synchronisiert. Wobei as StringBuilder veränderbar, aber standardmäßig nicht synchronisiert ist.

Bedeutung von synchronisiert (Synchronisation) : Wenn etwas synchronisiert ist, können mehrere Threads darauf zugreifen und es ohne Probleme oder Nebenwirkungen ändern. StringBuffer ist synchronisiert, sodass Sie es problemlos mit mehreren Threads verwenden können.

Welches wann verwenden? StringBuilder: Wenn Sie einen String benötigen, der geändert werden kann und nur ein Thread darauf zugreift und ihn ändert. StringBuffer: Wenn Sie einen String benötigen, der geändert werden kann, und mehrere Threads darauf zugreifen und ihn ändern.

Hinweis : Verwenden Sie StringBuffer nicht unnötig, dh verwenden Sie ihn nicht, wenn nur ein Thread ihn ändert und darauf zugreift, da er viel Code zum Sperren und Entsperren für die Synchronisierung enthält, der unnötig CPU-Zeit in Anspruch nimmt. Verwenden Sie keine Schlösser, es sei denn, dies ist erforderlich.

user1923551
quelle
2
Ich möchte nur erwähnen, dass die INDIVIDUAL-Methodenaufrufe von StringBuffer threadsicher sind. Wenn Sie jedoch mehrere Codezeilen haben, verwenden Sie einen synchronisierten Codeblock, um die Thread-Sicherheit mit einer Sperre / einem Monitor zu gewährleisten (wie üblich ...). Gehen Sie grundsätzlich nicht einfach davon aus, dass die Verwendung einer thread-sicheren Bibliothek die Thread-Sicherheit in IHREM Programm sofort garantiert!
Kevin Lee
57

In einzelnen Threads ist StringBuffer dank JVM-Optimierungen nicht wesentlich langsamer als StringBuilder . Und beim Multithreading können Sie einen StringBuilder nicht sicher verwenden.

Hier ist mein Test (kein Benchmark, nur ein Test):

public static void main(String[] args) {

    String withString ="";
    long t0 = System.currentTimeMillis();
    for (int i = 0 ; i < 100000; i++){
        withString+="some string";
    }
    System.out.println("strings:" + (System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuffer buf = new StringBuffer();
    for (int i = 0 ; i < 100000; i++){
        buf.append("some string");
    }
    System.out.println("Buffers : "+(System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuilder building = new StringBuilder();
    for (int i = 0 ; i < 100000; i++){
        building.append("some string");
    }
    System.out.println("Builder : "+(System.currentTimeMillis() - t0));
}

Ergebnisse:
Strings: 319740
Puffer: 23
Builder: 7!

Builder sind also schneller als Puffer und viel schneller als die Verkettung von Zeichenfolgen. Verwenden wir nun einen Executor für mehrere Threads:

public class StringsPerf {

    public static void main(String[] args) {

        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        //With Buffer
        StringBuffer buffer = new StringBuffer();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(buffer));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Buffer : "+ AppendableRunnable.time);

        //With Builder
        AppendableRunnable.time = 0;
        executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(builder));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Builder: "+ AppendableRunnable.time);

    }

   static void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); // code reduced from Official Javadoc for Executors
        try {
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow();
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (Exception e) {}
    }
}

class AppendableRunnable<T extends Appendable> implements Runnable {

    static long time = 0;
    T appendable;
    public AppendableRunnable(T appendable){
        this.appendable = appendable;
    }

    @Override
    public void run(){
        long t0 = System.currentTimeMillis();
        for (int j = 0 ; j < 10000 ; j++){
            try {
                appendable.append("some string");
            } catch (IOException e) {}
        }
        time+=(System.currentTimeMillis() - t0);
    }
}

Jetzt benötigen StringBuffers 157 ms für 100000 Anhänge. Es ist nicht der gleiche Test, aber im Vergleich zu den vorherigen 37 ms können Sie davon ausgehen, dass die Anhänge von StringBuffers bei Verwendung von Multithreading langsamer sind . Der Grund dafür ist, dass JIT / Hotspot / Compiler / Something Optimierungen vornimmt, wenn festgestellt wird, dass keine Überprüfung der Sperren erforderlich ist.

Aber mit StringBuilder haben Sie java.lang.ArrayIndexOutOfBoundsException , weil ein gleichzeitiger Thread versucht, etwas hinzuzufügen, wo es nicht sollte.

Fazit ist, dass Sie StringBuffers nicht verfolgen müssen. Und wo Sie Threads haben, überlegen Sie, was sie tun, bevor Sie versuchen, ein paar Nanosekunden zu gewinnen.

Nicolas Zozol
quelle
5
Sie haben vergessen, "t0 = System.currentTimeMillis ();" bevor Sie den StringBuilder-Test durchführen. Die für StringBuilder angezeigte Zahl ist also tatsächlich die Zeit, die zum Ausführen des Stringbuffer- UND Stringbuilder-Tests benötigt wurde. Fügen Sie diese Zeile hinzu und Sie werden sehen, dass StringBuilder ungefähr ZWEI MAL schneller ist.
Gena Batsyan
Beachten Sie, dass dies withString+="some string"+i+" ; ";nicht den beiden anderen Schleifen entspricht und daher kein fairer Vergleich ist.
Dave Jarvis
Genau, korrigiert. Gedankenstränge sind immer noch sehr langsam.
Nicolas Zozol
Können Sie mehr erklären, warum die ArrayIndexOutOfBoundsException für StringBuilder
Alireza Fattahi
Sie sollten JMH für Benchmarks verwenden. Ihr Benchmark ist wirklich ungenau.
Lukas Eder
42

StringBuilder wurde in Java 1.5 eingeführt, sodass es mit früheren JVMs nicht funktioniert.

Aus den Javadocs :

Die StringBuilder-Klasse bietet eine API, die mit StringBuffer kompatibel ist, jedoch keine Garantie für die Synchronisierung bietet. Diese Klasse ist als Drop-In-Ersatz für StringBuffer an Stellen vorgesehen, an denen der String-Puffer von einem einzelnen Thread verwendet wurde (wie dies im Allgemeinen der Fall ist). Nach Möglichkeit wird empfohlen, diese Klasse gegenüber StringBuffer zu verwenden, da sie bei den meisten Implementierungen schneller ist.

Marc Novakowski
quelle
13
1.4 ist am Ende seiner Lebensdauer, daher scheint es kaum wert zu sein, sich über die Zeit vor 1.5 Gedanken zu machen.
Tom Hawtin - Tackline
@ tomHawtin-Tackline nicht unbedingt - es gibt Enterprise-Produkte auf Version 1.4, die die meisten von uns täglich verwenden. Auch BlackBerry Java basiert auf 1.4 und das ist immer noch sehr aktuell.
Richard Le Mesurier
Und CDC und CLDC haben nicht StringBuilder.
Jin Kwon
37

Ziemlich gute Frage

Hier sind die Unterschiede, die ich bemerkt habe:

StringBuffer: -

StringBuffer is  synchronized
StringBuffer is  thread-safe
StringBuffer is  slow (try to write a sample program and execute it, it will take more time than StringBuilder)

StringBuilder: -

 StringBuilder is not synchronized 
 StringBuilder is not thread-safe
 StringBuilder performance is better than StringBuffer.

Verbreitete Sache :-

Beide haben dieselben Methoden mit denselben Signaturen. Beide sind veränderlich.

Sireesh Yarlagadda
quelle
23

StringBuffer

  • Synchronisiert daher threadsicher
  • Faden sicher daher langsam

StringBuilder

  • Eingeführt in Java 5.0
  • Asynchron, daher schnell und effizient
  • Der Benutzer muss es explizit synchronisieren, wenn er möchte
  • Sie können es durch ersetzen StringBuffer ohne weitere Änderungen
JRomio
quelle
HINWEIS: Nur einzelne Vorgänge sind threadsicher, mehrere Vorgänge nicht. zB wenn Sie rufen Sie appendzweimal, oder appendund toStringist nicht nicht sicher.
Peter Lawrey
22

StringBuilder ist nicht threadsicher. String Buffer ist. Mehr Infos hier .

BEARBEITEN: Was die Leistung betrifft, ist StringBuilder nach dem Start des Hotspots der Gewinner. Bei kleinen Iterationen ist der Leistungsunterschied jedoch vernachlässigbar.

Lernen
quelle
21

StringBuilderund StringBuffersind fast gleich. Der Unterschied ist, dass StringBuffersynchronisiert ist und StringBuildernicht. Obwohl, StringBuilderist schneller als StringBuffer, ist der Unterschied in der Leistung sehr gering. StringBuilderist der Ersatz einer SUN vonStringBuffer . Es wird lediglich die Synchronisation aller öffentlichen Methoden vermieden. Stattdessen ist ihre Funktionalität dieselbe.

Beispiel für eine gute Verwendung:

Wenn sich Ihr Text ändern wird und von mehreren Threads verwendet wird, ist es besser, ihn zu verwenden StringBuffer. Wenn sich Ihr Text ändern wird, aber von einem einzelnen Thread verwendet wird, verwenden Sie StringBuilder.

Subodh Ray
quelle
19

StringBuffer

StringBuffer ist veränderbar, dh man kann den Wert des Objekts ändern. Das über StringBuffer erstellte Objekt wird im Heap gespeichert. StringBuffer hat die gleichen Methoden wie der StringBuilder, aber jede Methode in StringBuffer ist synchronisiert, dh StringBuffer ist threadsicher.

Aus diesem Grund können nicht zwei Threads gleichzeitig auf dieselbe Methode zugreifen. Auf jede Methode kann jeweils ein Thread zugreifen.

Thread-sicher zu sein hat jedoch auch Nachteile, da die Leistung des StringBuffer aufgrund der thread-sicheren Eigenschaft beeinträchtigt wird. Daher ist StringBuilder schneller als der StringBuffer, wenn dieselben Methoden für jede Klasse aufgerufen werden.

Der StringBuffer-Wert kann geändert werden. Dies bedeutet, dass er dem neuen Wert zugewiesen werden kann. Heutzutage ist es eine häufig gestellte Interviewfrage, die Unterschiede zwischen den oben genannten Klassen. Der String-Puffer kann mithilfe der toString () -Methode in den String konvertiert werden.

StringBuffer demo1 = new StringBuffer(“Hello”) ;
// The above object stored in heap and its value can be changed .

demo1=new StringBuffer(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuffer

StringBuilder

StringBuilder ist dasselbe wie der StringBuffer, dh er speichert das Objekt im Heap und kann auch geändert werden. Der Hauptunterschied zwischen StringBuffer und StringBuilder besteht darin, dass StringBuilder auch nicht threadsicher ist. StringBuilder ist schnell, da es nicht threadsicher ist.

StringBuilder demo2= new StringBuilder(“Hello”);
// The above object too is stored in the heap and its value can be modified

demo2=new StringBuilder(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuilder

Geben Sie hier die Bildbeschreibung ein

Ressource: String Vs StringBuffer Vs StringBuilder

Affy
quelle
StringBuilder ist unveränderlich und String-Typ ist veränderlich
Brinda Rathod
Ich würde nicht zustimmen, dass Strings und StringBuilder "schnell" und StringBuffers "sehr langsam" sind. Siehe die obigen Antworten.
FireCubez
17

String ist eine unveränderliche.

StringBuffer ist veränderlich und synchronisiert.

StringBuilder ist auch veränderlich, aber nicht synchronisiert.

Sudhakar
quelle
Zusätzlich sperrt StringBuffer Threads für den Zugriff auf diese thread-sicheren Daten, weshalb der Vorgang langsam verläuft. StringBuilder sperrt den Thread nicht und wird auf Multi-Threading-Weise ausgeführt, weshalb es schnell geht. String - wenn Sie keinen String verketten müssen, ist dies ein guter Weg, aber wenn Sie ihn brauchen, verwenden Sie StringBuilder -> weil String jedes Mal ein neues Objekt im Heap erstellt, aber StringBuilder dasselbe Objekt zurückgibt ...
Musa
11

Der Javadoc erklärt den Unterschied:

Diese Klasse bietet eine API, die mit StringBuffer kompatibel ist, jedoch keine Garantie für die Synchronisierung bietet. Diese Klasse ist als Drop-In-Ersatz für StringBuffer an Stellen vorgesehen, an denen der String-Puffer von einem einzelnen Thread verwendet wurde (wie dies im Allgemeinen der Fall ist). Nach Möglichkeit wird empfohlen, diese Klasse gegenüber StringBuffer zu verwenden, da sie bei den meisten Implementierungen schneller ist.

Skaffman
quelle
10

StringBuilder (eingeführt in Java 5) ist identisch mit StringBuffer , außer dass seine Methoden nicht synchronisiert sind. Dies bedeutet, dass es eine bessere Leistung als das letztere hat, aber der Nachteil ist, dass es nicht threadsicher ist.

Lesen Sie das Tutorial für weitere Details.

Sébastien Le Callonnec
quelle
6

Ein einfaches Programm, das den Unterschied zwischen StringBuffer und StringBuilder veranschaulicht:

/**
 * Run this program a couple of times. We see that the StringBuilder does not
 * give us reliable results because its methods are not thread-safe as compared
 * to StringBuffer.
 * 
 * For example, the single append in StringBuffer is thread-safe, i.e.
 * only one thread can call append() at any time and would finish writing
 * back to memory one at a time. In contrast, the append() in the StringBuilder 
 * class can be called concurrently by many threads, so the final size of the 
 * StringBuilder is sometimes less than expected.
 * 
 */
public class StringBufferVSStringBuilder {

    public static void main(String[] args) throws InterruptedException {

        int n = 10; 

        //*************************String Builder Test*******************************//
        StringBuilder sb = new StringBuilder();
        StringBuilderTest[] builderThreads = new StringBuilderTest[n];
        for (int i = 0; i < n; i++) {
            builderThreads[i] = new StringBuilderTest(sb);
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].join();
        }
        System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());

        //*************************String Buffer Test*******************************//

        StringBuffer sb2 = new StringBuffer();
        StringBufferTest[] bufferThreads = new StringBufferTest[n];
        for (int i = 0; i < n; i++) {
            bufferThreads[i] = new StringBufferTest(sb2);
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].join();
        }
        System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());

    }

}

// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {

    StringBuilder sb;

    public StringBuilderTest (StringBuilder sb) {
        this.sb = sb;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb.append("A");
        }

    }
}


//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {

    StringBuffer sb2;

    public StringBufferTest (StringBuffer sb2) {
        this.sb2 = sb2;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb2.append("A");
        }

    }
}
Kevin Lee
quelle
4

StringBuffer wird zum Speichern von Zeichenfolgen verwendet, die geändert werden (String-Objekte können nicht geändert werden). Es wird bei Bedarf automatisch erweitert. Verwandte Klassen: String, CharSequence.

StringBuilder wurde in Java 5 hinzugefügt. Es ist in jeder Hinsicht identisch mit StringBuffer, außer dass es nicht synchronisiert ist. Wenn also mehrere Threads gleichzeitig darauf zugreifen, kann es zu Problemen kommen. Bei Single-Threaded-Programmen ist der StringBuilder der häufigste Fall, wenn der Synchronisierungsaufwand vermieden wird, der StringBuilder etwas schneller.


quelle
4
Single-Thread-Programme sind in Java nicht der häufigste Fall, aber sie StringBuildersind normalerweise lokal für eine Methode, bei der sie nur für einen Thread sichtbar sind.
Finnw
4

StringBufferist synchronisiert, aber StringBuildernicht. Infolgedessen StringBuilderist schneller als StringBuffer.

Ahmad Adawi
quelle
4

StringBuffer ist veränderbar. Es kann sich in Länge und Inhalt ändern. StringBuffers sind threadsicher, dh sie verfügen über synchronisierte Methoden zur Steuerung des Zugriffs, sodass jeweils nur ein Thread auf den synchronisierten Code eines StringBuffer-Objekts zugreifen kann. Daher können StringBuffer-Objekte in einer Umgebung mit mehreren Threads, in der möglicherweise mehrere Threads gleichzeitig versuchen, auf dasselbe StringBuffer-Objekt zuzugreifen, im Allgemeinen sicher verwendet werden.

StringBuilder Die StringBuilder-Klasse ist StringBuffer sehr ähnlich, außer dass ihr Zugriff nicht synchronisiert ist, sodass sie nicht threadsicher ist. Wenn Sie nicht synchronisiert sind, kann die Leistung von StringBuilder besser sein als die von StringBuffer. Wenn Sie in einer Umgebung mit einem Thread arbeiten, kann die Verwendung von StringBuilder anstelle von StringBuffer zu einer Leistungssteigerung führen. Dies gilt auch für andere Situationen, z. B. eine lokale StringBuilder-Variable (dh eine Variable innerhalb einer Methode), in der nur ein Thread auf ein StringBuilder-Objekt zugreift.

Android Genius
quelle
4

StringBuffer:

  • Multi Thread
  • Synchronisiert
  • Langsam als StringBuilder

StringBuilder

  • Single-Thread
  • Nicht synchronisiert
  • Schneller als je zuvor String
Asif Mushtaq
quelle
2
Genauer gesagt String c = a + bist gleichbedeutend mit String c = new StringBuilder().append(a).append(b).toString(), also ist es nicht schneller. Es ist nur , dass Sie eine neue für jede Saite assignation erstellen, während Sie nur eine haben könnte ( String d = a + b; d = d + c;ist String d = new StringBuilder().append(a).append(b).toString(); d = new StringBuilder().append(d).append(c).toString();während StringBuilder sb = new StringBuilder(); sb.append(a).append(b); sb.append(c); String d = sb.toString();würde man String Instanciation speichern).
Hieb
4

String-Builder :

int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n');
System.out.print(sb);
// Prints "One=1, Colour=red" followed by an ASCII newline.

String-Puffer

StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);  

Es wird empfohlen, nach Möglichkeit StringBuilder zu verwenden, da dieser schneller als StringBuffer ist. Wenn jedoch die Thread-Sicherheit erforderlich ist, sind StringBuffer-Objekte die beste Option.

Avinash
quelle
Wenn Sie Thread-Sicherheit benötigen, ist die beste Option die Verwendung von StringBuilder, da StringBuffer nur für einzelne Vorgänge threadsicher ist. Für mehrere Vorgänge benötigen Sie eine explizite Sperrung.
Peter Lawrey
4

Bessere Verwendung, StringBuilderda es nicht synchronisiert ist und daher eine bessere Leistung bietet. StringBuilderist ein Ersatz für die älteren StringBuffer.

Niclas
quelle
3
@Mark true, aber meistens StringBu(ff|ild)erist das eine lokale Variable, die nur von einem einzelnen Thread verwendet wird.
Gabuzo
1
@MarkMcKenna: Selbst in einer Multithread-Anwendung müsste man oft entweder eine externe Sperre verwenden oder zusätzliche Arbeit leisten, um dies zu vermeiden. Wenn beispielsweise zwei Threads jeweils einen Datensatz mit mehreren Zeichenfolgen an einen Stringbuilder anhängen möchten, müssen sie die hinzuzufügenden Daten aggregieren und dann als Einheit hinzufügen, selbst wenn dies schneller gewesen wäre - ohne Threading-Probleme. um einfach eine Folge von diskreten Anhängeoperationen auszuführen.
Supercat
3

Da StringBufferes synchronisiert ist, erfordert es einige zusätzliche Anstrengungen, daher ist es aufgrund der Leistung etwas langsamer als StringBuilder.

Shuhail Kadavath
quelle
3

Es gibt keine grundlegenden Unterschiede zwischen StringBuilderund StringBuffer, es gibt nur wenige Unterschiede zwischen ihnen. In StringBufferden Methoden werden synchronisiert. Dies bedeutet, dass jeweils nur ein Thread mit ihnen arbeiten kann. Wenn es mehr als einen Thread gibt, muss der zweite Thread warten, bis der erste beendet ist, und der dritte muss warten, bis der erste und der zweite Thread beendet sind und so weiter. Dies macht den Prozess sehr langsam und damit die Leistung im Fall vonStringBuffer gering.

Ist andererseits StringBuildernicht synchronisiert. Dies bedeutet, dass mehrere Threads gleichzeitig an demselben StringBuilderObjekt arbeiten können. Dies macht den Prozess sehr schnell und daher ist die Leistung von StringBuilderhoch.

Pratik Paul
quelle
3

A Stringist ein unveränderliches Objekt, was bedeutet, dass der Wert nicht geändert werden kann, während er StringBufferveränderbar ist.

Das StringBufferist synchronisiert und daher threadsicher, während StringBuilderes nicht nur für Instanzen mit einem Thread geeignet ist.

Ketan Patel
quelle
3
Nur weil StringBuffer Code synchronisiert hat, bedeutet dies nicht unbedingt, dass StringBuffer threadsicher ist. Betrachten Sie das folgende Beispiel: StringBuffer testingBuffer = "stackoverflow"; Jetzt versucht Thread-1, "1" an testingBuffer anzuhängen, und Thread-2 versucht, "2" an testingBuffer anzuhängen. Obwohl die append () -Methode synchronisiert ist, können Sie nicht sicher sein, ob der Wert von testingBuffer "stackoverflow12" oder "stackoverflow21" ist. Tatsächlich wird von Oracle empfohlen, Stringbuilder anstelle von Stringbuffer zu verwenden. Ich hoffe das hat geholfen :)
Biman Tripathy
2

Der Hauptunterschied besteht darin, dass er synchronisiert StringBufferist, aber nicht. StringBuilderWenn Sie mehr als einen Thread verwenden müssen, wird StringBuffer empfohlen. Die Ausführungsgeschwindigkeit StringBuilderist jedoch schneller als StringBuffer, da er nicht synchronisiert ist.

JDGuide
quelle
4
StringBuffer ist nur threadsicher, wenn Sie nur eine Operation ausführen. Ich würde nicht empfehlen, es in mehreren Threads zu verwenden, da es sehr schwierig ist, es richtig zu machen.
Peter Lawrey
@ PeterLawrey was meinst du? :-)
Tamad Lang
1
@ b16db0 Ich meine, dass die meisten Verwendungen von StringBuffer nicht threadsicher sind, da sie ohne externe Synchronisation mehrere Aufrufe ausführen, was die Klasse ziemlich sinnlos macht.
Peter Lawrey
@PeterLawrey ah, es ist, als ob StringBuffer immer noch eine synchronisierte Umgebung benötigt.
Tamad Lang
2

Überprüfen Sie die Interna der synchronisierten Append-Methode StringBufferund der nicht synchronisierten Append-Methode von StringBuilder.

StringBuffer :

public StringBuffer(String str) {
    super(str.length() + 16);
    append(str);
}

public synchronized StringBuffer append(Object obj) {
    super.append(String.valueOf(obj));
    return this;
}

public synchronized StringBuffer append(String str) {
    super.append(str);
    return this;
}

StringBuilder :

public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}

public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

Da Anhängen ist synchronized, StringBufferhat Leistung Overhead im Vergleich zu StrinbBuilderMultithreading-Szenario. Solange Sie den Puffer nicht für mehrere Threads freigeben, verwenden Sie StringBuilder, was aufgrund des Fehlens von synchronizedMethoden zum Anhängen schnell ist .

Ravindra Babu
quelle
1

Hier ist das Ergebnis des Leistungstests für String vs StringBuffer vs StringBuilder . Schließlich gewann StringBuilder den Test. Siehe unten für Testcode und Ergebnis.

Code :

private static void performanceTestStringVsStringbuffereVsStringBuilder() {
// String vs StringBiffer vs StringBuilder performance Test

int loop = 100000;
long start = 0;

// String
String str = null;
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  str += i + "test";
}
System.out.println("String - " + (System.currentTimeMillis() - start) + " ms");

// String buffer
StringBuffer sbuffer = new StringBuffer();
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Buffer - " + (System.currentTimeMillis() - start) + " ms");

// String builder
start = System.currentTimeMillis();
StringBuilder sbuilder = new StringBuilder();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Builder - " + (System.currentTimeMillis() - start) + " ms");

  }

Führe mich auf ideone aus

Ergebnis :

100000 Iteration zum Hinzufügen eines einzelnen Textes

String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms

10000 Iteration zum Hinzufügen eines einzelnen Textes

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms
Ganesa Vijayakumar
quelle
1
  • StringBuffer ist threadsicher, aber StringBuilder ist nicht threadsicher.
  • StringBuilder ist schneller als StringBuffer.
  • StringBuffer ist synchronisiert, während StringBuilder nicht synchronisiert ist.
Praveen Kishor
quelle
1

StringBuffer ist synchronisiert und threadsicher, StringBuilder ist nicht synchronisiert und schneller.

G. Brown
quelle
Dieser Unterschied wurde in allen anderen Antworten auf diese Frage angegeben. Könnten Sie etwas Neues hervorheben?
Nico Haase