StringBuilder和StringBuffer的区别

1734

StringBufferStringBuilder的主要区别是什么?在决定使用其中任何一个时是否存在性能问题?

33个回答

4

StringBuffer 是同步的,但是 StringBuilder 不是。因此,StringBuilderStringBuffer 更快。


4

StringBuffer是可变的。它可以在长度和内容方面发生改变。StringBuffer是线程安全的,意味着它们有同步方法来控制访问,以便只有一个线程可以同时访问StringBuffer对象的同步代码。因此,在多线程环境中,多个线程可能会尝试同时访问同一StringBuffer对象的情况下,StringBuffer对象通常是安全使用的。

StringBuilder类与StringBuffer非常相似,但其访问未同步,因此不是线程安全的。由于没有同步,StringBuilder的性能可能比StringBuffer更好。因此,如果您在单线程环境中工作,使用StringBuilder而不是StringBuffer可能会提高性能。这也适用于其他情况,如仅有一个线程将访问StringBuilder对象的局部变量(即方法内的变量)。


4

String是一个不可变的对象,这意味着它的值不能被改变,而StringBuffer是可变的。

StringBuffer是同步的,因此线程安全,而StringBuilder则不是,并且适合于仅限单线程的实例。


4
虽然StringBuffer的代码是同步的,但这并不意味着它一定是线程安全的。考虑以下示例: StringBuffer testingBuffer = "stackoverflow"; 现在Thread-1正在尝试将“1”附加到testingBuffer,而Thread-2正在尝试将“2”附加到testingBuffer。即使append()方法是同步的,您也无法确定testingBuffer的值是“stackoverflow12”还是“stackoverflow21”。 实际上,Oracle建议使用StringBuilder而不是StringBuffer。希望这有所帮助 :) - Biman Tripathy
@BimanTripathy上面的观点实际上是对多线程活动的观察:通过线程安全,我们将知道"1"和"2"都将被追加到"stackoverflow"中,但我们不知道它们的顺序。如果没有线程安全,"1"和"2"可能都会被追加,但我们也可能有一个线程撤销另一个线程所做的工作,或者两个线程破坏他们使用的结构的内部状态。 - Luis

4

StringBuffer 用于存储需要更改的字符字符串(String 对象无法更改)。它会根据需要自动扩展。相关类:String、CharSequence。

Java 5 中添加了 StringBuilder。它在所有方面与 StringBuffer 相同,除了它不是同步的,这意味着如果多个线程同时访问它,则可能会出现问题。对于单线程程序(最常见的情况),避免同步开销使 StringBuilder 稍微更快。


4
单线程程序在Java中并不是最常见的情况,但StringBuilder通常只存在于一个方法中,并且仅对一个线程可见。 - finnw

3

StringBuffer 是同步的,因此需要额外的努力,因此基于性能考虑,它比 StringBuilder 稍慢。


3
StringBuilderStringBuffer之间没有基本区别,只存在一些细微的差别。在StringBuffer中,方法是同步的。这意味着一次只有一个线程可以对它们进行操作。如果有多个线程,则第二个线程将不得不等待第一个线程完成,第三个线程将不得不等待第一个和第二个线程完成,以此类推。这使得在StringBuffer的情况下进程非常缓慢,因此性能较低。
另一方面,StringBuilder没有同步。这意味着同时可以有多个线程在同一个StringBuilder对象上进行操作。这使得进程非常快,因此StringBuilder的性能很高。

2

查看StringBuffer的同步追加方法和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;
}

由于append是synchronized的,所以在多线程情况下,StringBuffer相对于StringBuilder会有性能开销。只要您不将缓冲区在多个线程之间共享,请使用StringBuilder,因为其在append方法中没有synchronized,因此速度很快。


2

主要的区别在于StringBuffer是同步的,而StringBuilder不是。如果需要使用多个线程,则建议使用StringBuffer。但是就执行速度而言,StringBuilderStringBuffer更快,因为它不是同步的。


4
如果您在StringBuffer上执行一个操作,它只是线程安全的。我不建议在多个线程中使用它,因为很难正确实现。大多数StringBuffer的用法都不是线程安全的,因为它们在没有外部同步的情况下对它进行多次调用,使得这个类相当无意义。 - Peter Lawrey

1
以下是关于 String vs StringBuffer vs StringBuilder 的性能测试结果。最终,StringBuilder 获胜。请参见下面的测试代码和结果。

代码:

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");

  }

在ideone上执行我

结果:

添加单个文本的100000次迭代

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

10000次迭代,用于添加单个文本

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms

1
  • StringBuffer是线程安全的,但StringBuilder不是线程安全的。
  • StringBuilder比StringBuffer更快。
  • StringBuffer是同步的,而StringBuilder不是同步的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接