StringBuffer
和StringBuilder
的主要区别是什么?在决定使用其中任何一个时是否存在性能问题?
StringBuffer
和StringBuilder
的主要区别是什么?在决定使用其中任何一个时是否存在性能问题?
StringBuffer
是同步的,但是 StringBuilder
不是。因此,StringBuilder
比 StringBuffer
更快。
StringBuffer是可变的。它可以在长度和内容方面发生改变。StringBuffer是线程安全的,意味着它们有同步方法来控制访问,以便只有一个线程可以同时访问StringBuffer对象的同步代码。因此,在多线程环境中,多个线程可能会尝试同时访问同一StringBuffer对象的情况下,StringBuffer对象通常是安全使用的。
StringBuilder类与StringBuffer非常相似,但其访问未同步,因此不是线程安全的。由于没有同步,StringBuilder的性能可能比StringBuffer更好。因此,如果您在单线程环境中工作,使用StringBuilder而不是StringBuffer可能会提高性能。这也适用于其他情况,如仅有一个线程将访问StringBuilder对象的局部变量(即方法内的变量)。
String
是一个不可变的对象,这意味着它的值不能被改变,而StringBuffer
是可变的。
StringBuffer
是同步的,因此线程安全,而StringBuilder
则不是,并且适合于仅限单线程的实例。
StringBuffer 用于存储需要更改的字符字符串(String 对象无法更改)。它会根据需要自动扩展。相关类:String、CharSequence。
Java 5 中添加了 StringBuilder。它在所有方面与 StringBuffer 相同,除了它不是同步的,这意味着如果多个线程同时访问它,则可能会出现问题。对于单线程程序(最常见的情况),避免同步开销使 StringBuilder 稍微更快。
StringBuffer
是同步的,因此需要额外的努力,因此基于性能考虑,它比 StringBuilder
稍慢。
StringBuilder
和StringBuffer
之间没有基本区别,只存在一些细微的差别。在StringBuffer
中,方法是同步的。这意味着一次只有一个线程可以对它们进行操作。如果有多个线程,则第二个线程将不得不等待第一个线程完成,第三个线程将不得不等待第一个和第二个线程完成,以此类推。这使得在StringBuffer
的情况下进程非常缓慢,因此性能较低。StringBuilder
没有同步。这意味着同时可以有多个线程在同一个StringBuilder
对象上进行操作。这使得进程非常快,因此StringBuilder
的性能很高。查看StringBuffer
的同步追加方法和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;
}
由于append是synchronized
的,所以在多线程情况下,StringBuffer
相对于StringBuilder
会有性能开销。只要您不将缓冲区在多个线程之间共享,请使用StringBuilder
,因为其在append方法中没有synchronized
,因此速度很快。
主要的区别在于StringBuffer
是同步的,而StringBuilder
不是。如果需要使用多个线程,则建议使用StringBuffer。但是就执行速度而言,StringBuilder
比StringBuffer
更快,因为它不是同步的。
代码:
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");
}
结果:
添加单个文本的100000次迭代
String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms
10000次迭代,用于添加单个文本
String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms