StringBuffer和StringBuilder之间的主要区别是什么?在决定其中任何一项时是否存在性能问题?
当前回答
首先让我们看看相似之处:StringBuilder和StringBuffer都是可变的。这意味着您可以在同一位置更改它们的内容。
差异:StringBuffer也是可变的和同步的。其中,作为StringBuilder是可变的,但默认情况下不同步。
同步(synchronization)的含义:当某些东西被同步时,多个线程可以访问并修改它,而不会产生任何问题或副作用。StringBuffer是同步的,因此您可以在多个线程中使用它,而不会出现任何问题。
何时使用哪一个?StringBuilder:当您需要一个可以修改的字符串,并且只有一个线程在访问和修改它时。StringBuffer:当您需要一个可以修改的字符串,并且多个线程正在访问和修改它时。
注意:不要不必要地使用StringBuffer,也就是说,如果只有一个线程在修改和访问它,就不要使用它,因为它有很多用于同步的锁定和解锁代码,这将不必要地占用CPU时间。除非需要,否则不要使用锁。
其他回答
StringBuffer中的每个方法都是同步的。因此,一次只允许一个线程操作StringBuffer对象。它增加了线程的等待时间并造成性能问题为了解决这个问题,SUN People推出了1.5版本的StringBuilder。
下面是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
字符串是不可变的。
StringBuffer是一个可变的和同步的。
StringBuilder也是可变的,但不同步。
StringBuilder比StringBuffer更快,因为StringBuffer是同步的,StringBuffer有自己的char[]缓冲区用于缓存,就像BufferedInputStream一样。
StringBuffer速度较慢的另一个原因是,每次添加或删除时,它都会更新变量缓冲区。我测试了它,如果我移除超过一万次,StringBuffer的移除方法会更快。
检查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;
}
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;
}
由于追加是同步的,因此与多线程场景中的StrinbBuilder相比,StringBuffer具有性能开销。只要不在多个线程之间共享缓冲区,就可以使用StringBuilder,因为缺少同步的追加方法,所以速度很快。
推荐文章
- 使用Java重命名文件
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?
- Java 8流和数组操作
- Java Regex捕获组
- Openssl不被视为内部或外部命令
- 如何添加自定义方法到Spring Data JPA
- 如何在Ubuntu中设置Java环境路径
- 无法执行dex:在Eclipse中超过GC开销限制
- 有人能解释一下JPA和Hibernate中的mappedBy吗?
- 是什么导致JNI调用变慢?
- Java中的&和&&有什么区别?
- 使用Java的Collections.singletonList()?
- Maven使用多个src目录编译