Wat is het belangrijkste verschil tussen StringBuffer
en StringBuilder
?
Zijn er prestatieproblemen bij het bepalen van een van deze?
1, Autoriteit 100%
StringBuffer
is gesynchroniseerd, StringBuilder
is dat niet.
2, Autoriteit 43%
StringBuilder
is sneller dan StringBuffer
omdat het niet synchronized
.
Hier is een eenvoudige benchmarktest:
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);
}
}
}
a test uitgevoerd geeft de nummers 2241 ms
voor StringBuffer
versus 753 ms
voor StringBuilder
.
3, Autoriteit 15%
In principe, StringBuffer
methoden worden gesynchroniseerd terwijl StringBuilder
niet.
De bewerkingen zijn “bijna” hetzelfde, maar met behulp van gesynchroniseerde methoden in een enkele draad is overkill.
Dat is er vrij veel over.
Citaat van stringbuilder API :
Deze klasse [stringbuilder] biedt een API-compatibel met stringbuffer, , maar zonder garantie voor synchronisatie . Deze klasse is ontworpen voor gebruik als een drop-in vervanging voor stringbuffer op plaatsen waar de snaarbuffer werd gebruikt door een enkele draad (zoals in het algemeen het geval is). Waar mogelijk wordt aanbevolen dat deze klasse wordt gebruikt in voorkeur aan stringbuffer als het zal sneller zijn onder de meeste implementaties.
Dus het is gemaakt om het te vervangen.
hetzelfde gebeurde met Vector
en ArrayList
.
4, Autoriteit 11%
Maar nodig om het duidelijke verschil te krijgen met behulp van een voorbeeld?
stringbuffer of stringbuilder
Gebruik eenvoudig StringBuilder
Tenzij u echt probeert een buffer tussen threads te delen. StringBuilder
is de niet-gesynchroniseerde (minder overhead = efficiënter) jongere broer van de originele gesynchroniseerde StringBuffer
klasse.
StringBuffer
kwam eerst. De zon was onder alle omstandigheden zich bezig met juistheid, zodat ze het hebben gesynchroniseerd om het draadveilig te maken voor het geval dat.
StringBuilder
kwam later. De meeste toepassingen van StringBuffer
waren single-thread en betaalden onnodig de kosten van de synchronisatie.
Aangezien StringBuilder
een drop-in vervangingis voor StringBuffer
zonder de synchronisatie, zouden er geen verschillen zijn tussen alle voorbeelden.
Als u probeertte delen tussen threads, kunt u StringBuffer
gebruiken, maar overweeg of synchronisatie op een hoger niveau nodig is, b.v. misschien in plaats van StringBuffer te gebruiken, moet u de methoden synchroniseren die de StringBuilder gebruiken.
Antwoord 5, autoriteit 5%
Laten we eerst de overeenkomstenbekijken:
Zowel StringBuilder als StringBuffer zijn veranderlijk. Dat betekent dat je de inhoud ervan kunt wijzigen, op dezelfde locatie.
Verschillen:
StringBuffer is ook veranderlijk en gesynchroniseerd. Waar als StringBuilder veranderlijk is maar niet standaard gesynchroniseerd.
Betekenis van gesynchroniseerd (synchronisatie):
Wanneer iets is gesynchroniseerd, kunnen meerdere threads toegang krijgen en het wijzigen zonder enig probleem of neveneffect.
StringBuffer is gesynchroniseerd, dus je kunt het zonder problemen met meerdere threads gebruiken.
Welke wanneer gebruiken?
StringBuilder : wanneer u een string nodig heeft, die kan worden gewijzigd, en slechts één thread heeft toegang tot deze en wijzigt deze.
StringBuffer: wanneer u een string nodig heeft, die kan worden gewijzigd, en meerdere threads openen en wijzigen deze.
Opmerking: gebruik StringBuffer niet onnodig, dwz gebruik het niet als slechts één thread het aanpast en opent, omdat het veel vergrendelings- en ontgrendelingscode heeft voor synchronisatie, wat onnodig veel tijd kost. CPU-tijd op. Gebruik geen sloten tenzij dit vereist is.
6, autoriteit 3%
In single threads, StringBuffer is niet significant langzamer dan StringBuilder , dankzij JVM optimalisaties. En in multithreading, kun je niet veilig gebruik maken van een StringBuilder.
Hier is mijn test (geen benchmark, maar een 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));
}
Resultaten:
strings: 319.740
Buffers: 23
Builder: 7
Dus Builders zijn sneller dan Buffers, en veel sneller dan strings aaneenschakeling.
Laten we nu gebruik maken van een Uitvoerder voor meerdere 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);
}
}
Nu buffers nemen 157 ms voor 100000 appliceren. Het is niet dezelfde test, maar in vergelijking met de vorige 37 MS kun je veilig aannemen dat stringbuffers bijlagen langzamer zijn met multithreading gebruik . De reden is dat de JIT / hotspot / compiler / iets optimalisaties maakt wanneer het detecteert dat er no nodig is om vergrendelingen te controleren.
Maar met stringbuilder, je hebt Java.lang.arrayindexoutofboundsexception , omdat een gelijktijdige draad iets probeert toe te voegen waar het niet mag toevoegen.
Conclusie is dat u geen stringbuffers hoeft te chase. En waar je draden hebt, denk dan na over wat ze doen, voordat je probeert een paar nanoseconden te behalen.
7, Autoriteit 2%
StringBuilder werd geïntroduceerd in Java 1.5, dus het zal niet werken met eerdere JVM’s.
van de Javadocs :
StringBuilder Klasse biedt een API-compatibel met stringbuffer, maar zonder garantie voor synchronisatie. Deze klasse is ontworpen voor gebruik als een drop-in vervanging voor stringbuffer op plaatsen waar de snaarbuffer werd gebruikt door een enkele draad (zoals in het algemeen het geval is). Waar mogelijk wordt aanbevolen dat deze klasse wordt gebruikt in voorkeur aan stringbuffer, omdat het sneller zal zijn onder de meeste implementaties.
8, Autoriteit 2%
Vrij goede vraag
Hier zijn de verschillen, ik heb gemerkt:
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.
Veelvoorkomende zaak:-
Beide hebben dezelfde methoden met dezelfde handtekeningen. Beide zijn veranderlijk.
Antwoord 9
StringBuffer
- Gesynchroniseerd en dus threadsafe
- Thread safe dus traag
StringBuilder
- Geïntroduceerd in Java 5.0
- Asynchroon dus snel & efficiënt
- Gebruiker moet het expliciet synchroniseren, als hij dat wil
- Je kunt het vervangen door
StringBuffer
zonder enige andere wijziging
Antwoord 10
StringBuilder is niet thread-safe. Stringbuffer is. Meer info hier .
EDIT: Wat de prestaties betreft, nadat hotspotis begonnen, is StringBuilder de winnaar. Voor kleine iteraties is het prestatieverschil echter verwaarloosbaar.
Antwoord 11
StringBuffer
StringBuffer is veranderlijk, wat betekent dat men de waarde van het object kan wijzigen. Het object dat met StringBuffer is gemaakt, wordt in de heap opgeslagen. StringBuffer heeft dezelfde methoden als de StringBuilder , maar elke methode in StringBuffer is gesynchroniseerd, waardoor StringBuffer threadveilig is .
Hierdoor kunnen twee threads niet tegelijkertijd toegang krijgen tot dezelfde methode . Elke methode is toegankelijk voor één thread tegelijk.
Maar thread-safe zijn heeft ook nadelen, aangezien de prestaties van de StringBuffer te wijten zijn aan de thread-safe-eigenschap . StringBuilder is dus sneller dan de StringBuffer bij het aanroepen van dezelfde methoden van elke klasse.
StringBuffer-waarde kan worden gewijzigd, dit betekent dat deze kan worden toegewezen aan de nieuwe waarde. Tegenwoordig is het een meest voorkomende interviewvraag, de verschillen tussen de bovenstaande klassen.
String Buffer kan worden geconverteerd naar de string met behulp van
toString() methode.
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 is hetzelfde als de StringBuffer , dat wil zeggen dat het het object in heap opslaat en het kan ook worden gewijzigd . Het belangrijkste verschil tussen StringBuffer en StringBuilder is dat StringBuilder ook niet thread-safe is.
StringBuilder is snel omdat het niet thread-safe is.
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
Bron: String versus StringBuffer versus StringBuilder
Antwoord 12
StringBuilder
en StringBuffer
zijn bijna hetzelfde. Het verschil is dat StringBuffer
gesynchroniseerd is en StringBuilder
niet. Hoewel StringBuilder
sneller is dan StringBuffer
, is het prestatieverschil erg klein. StringBuilder
is een SUN-vervanging van StringBuffer
. Het vermijdt gewoon synchronisatie van alle openbare methoden. In plaats daarvan is hun functionaliteit hetzelfde.
Voorbeeld van goed gebruik:
Als je tekst gaat veranderen en door meerdere threads wordt gebruikt, is het beter om StringBuffer
te gebruiken. Als je tekst gaat veranderen maar door een enkele thread wordt gebruikt, gebruik dan StringBuilder
.
Antwoord 13
String
is een onveranderlijk.
StringBuffer
is een veranderlijk en gesynchroniseerd.
StringBuilder
kan ook worden gewijzigd, maar is niet gesynchroniseerd.
Antwoord 14
De javadoclegt het verschil uit:
Deze klasse biedt een API die compatibel is met StringBuffer, maar zonder garantie op synchronisatie. Deze klasse is ontworpen voor gebruik als een drop-in vervanging voor StringBuffer op plaatsen waar de stringbuffer werd gebruikt door een enkele thread (zoals in het algemeen het geval is). Waar mogelijk wordt aanbevolen deze klasse te gebruiken in plaats van StringBuffer, aangezien deze bij de meeste implementaties sneller zal zijn.
Antwoord 15
StringBuilder
(geïntroduceerd in Java 5) is identiek aan StringBuffer
, behalve dat de methoden niet gesynchroniseerd zijn. Dit betekent dat het betere prestaties levert dan het laatste, maar het nadeel is dat het niet thread-safe is.
Lees Tutorial voor meer details.
16
Een eenvoudig programma illustreert het verschil tussen stringbuffer en stringbuilder:
/**
* 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");
}
}
}
17
Verschil tussen stringbuffer en stringbuilder Bron:
18
Stringbuffer wordt gebruikt om tekenreeksen op te slaan die zullen worden gewijzigd (string-objecten kunnen niet worden gewijzigd). Het breidt zich automatisch uit als dat nodig is. Gerelateerde klassen: string, chariquate.
StringBuilder is toegevoegd in Java 5. Het is in alle opzichten identiek aan StringBuffer, behalve dat het niet gesynchroniseerd is, wat betekent dat als meerdere threads er tegelijkertijd toegang toe hebben, er problemen kunnen ontstaan. Voor programma’s met één thread, het meest voorkomende geval, maakt het vermijden van de overhead van synchronisatie de StringBuilder iets sneller.
Antwoord 19
StringBuffer
is gesynchroniseerd, maar StringBuilder
niet. Als gevolg hiervan is StringBuilder
sneller dan StringBuffer
.
Antwoord 20
StringBuffer
is veranderlijk. Het kan veranderen in lengte en inhoud. StringBuffers zijn thread-safe, wat betekent dat ze gesynchroniseerde methoden hebben om de toegang te regelen, zodat slechts één thread tegelijkertijd toegang heeft tot de gesynchroniseerde code van een StringBuffer-object. StringBuffer-objecten zijn dus over het algemeen veilig om te gebruiken in een omgeving met meerdere threads waar meerdere threads tegelijkertijd toegang proberen te krijgen tot hetzelfde StringBuffer-object.
StringBuilder
De klasse StringBuilder lijkt erg op StringBuffer, behalve dat de toegang niet is gesynchroniseerd, zodat deze niet thread-safe is. Door niet te synchroniseren, kunnen de prestaties van StringBuilder beter zijn dan die van StringBuffer. Als u dus in een omgeving met één thread werkt, kan het gebruik van StringBuilder in plaats van StringBuffer resulteren in betere prestaties. Dit geldt ook voor andere situaties, zoals een lokale variabele van StringBuilder (dwz een variabele binnen een methode) waarbij slechts één thread toegang heeft tot een StringBuilder-object.
Antwoord 21
StringBuffer:
- Multi-thread
- Gesynchroniseerd
- Langzaam dan StringBuilder
StringBuilder
- Enkeldraads
- Niet-gesynchroniseerd
- Sneller dan ooit String
22
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-buffer
StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);
Het wordt aanbevolen om een stringbuilder te gebruiken waar mogelijk omdat het sneller is dan stringbuffer. Als de draadveiligheid echter nodig is, is de beste optie Stringbuffer-objecten.
23
Gebruik beter StringBuilder
Omdat het niet is gesynchroniseerd en biedt daarom betere prestaties. StringBuilder
is een drop-in vervanging van de oudere StringBuffer
.
24
Aangezien StringBuffer
is gesynchroniseerd, heeft het wat extra inspanning nodig, vandaar op basis van perforamance, het is een beetje traag dan StringBuilder
.
25
Het belangrijkste verschil is StringBuffer
is gesynchroniseerd, maar StringBuilder
is niet. Als u meer dan één draad moet gebruiken, is StringBuffer aanbevolen. MAAR, volgens de uitvoering Snelheid StringBuilder
is sneller dan StringBuffer
, omdat het niet gesyncrroomiseerd is.
26
Controleer de internals van gesynchroniseerde append methode van StringBuffer
en niet-gesynchroniseerde append methode van StringBuilder
.
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;
}
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;
}
Aangezien append synchronized
is, heeft StringBuffer
prestatieoverhead vergeleken met StrinbBuilder
in multi-threading scenario. Zolang je geen buffer deelt tussen meerdere threads, gebruik je StringBuilder
, wat snel is vanwege het ontbreken van synchronized
in append-methoden.
Antwoord 27
Hier is het resultaat van de prestatietest voor String vs StringBuffer vs StringBuilder. Uiteindelijk won StringBuilder de test. Zie hieronder voor testcode en resultaat.
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");
}
Resultaat:
100000 iteratie voor het toevoegen van een enkele tekst
String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms
10000 iteratie voor het toevoegen van een enkele tekst
String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms
Antwoord 28
- StringBuffer is thread-safe, maar StringBuilder is niet thread-safe.
- StringBuilder is sneller dan StringBuffer.
- StringBuffer is gesynchroniseerd, StringBuilder niet
gesynchroniseerd.