StringBuffer和StringBuilder之间的主要区别是什么?在决定其中任何一项时是否存在性能问题?


当前回答

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

其他回答

但需要借助一个例子来明确区别吗?StringBuffer或StringBuilder

只需使用StringBuilder,除非您确实试图在线程之间共享缓冲区。StringBuilder是原始同步StringBuffer类的非同步(开销更少=效率更高)弟弟。

StringBuffer排名第一。Sun关注所有条件下的正确性,因此他们使其同步,以使其线程安全,以防万一。

StringBuilder后来出现了。StringBuffer的大多数使用都是单线程的,不必要地支付了同步的成本。

由于StringBuilder是没有同步的StringBuffer的替代品,因此任何示例之间都不会有差异。

如果您试图在线程之间共享,可以使用StringBuffer,但要考虑是否需要更高级别的同步,例如,如果您同步使用StringBuilder的方法,可能不需要使用StringBuffer。

下面是Stringvs 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

StringBuilder比StringBuffer更快,因为它不同步。

下面是一个简单的基准测试:

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

测试运行得出StringBuffer为2241ms,StringBuilder为753ms。

更好地使用StringBuilder,因为它不是同步的,因此提供了更好的性能。StringBuilder是旧StringBuffer的替代品。

StringBuilder是在Java1.5中引入的,因此它不能与早期的JVM一起使用。

从Javadocs:

StringBuilder类提供了与StringBuffer兼容的API,但不能保证同步。该类被设计为在单个线程使用字符串缓冲区的地方(通常情况下)作为StringBuffer的替代品。在可能的情况下,建议优先使用该类而不是StringBuffer,因为在大多数实现中,它会更快。