StringBuilder与StringBuffer: 单线程与多线程选择

一、基础理解

在Java中,当我们频繁拼接字符串时,String的+=方式效率太低,因为每次都会创建新对象。于是Java提供了两个可变的字符串类:StringBuilder和StringBuffer。
它们都可以被看作是可以修改的字符串容器。你往里面放内容,它不会创建新对象,而是直接修改内部存储。String是不可变的,每次修改都产生新对象;而StringBuilder和StringBuffer是可变的,修改操作只改变自身内容。

二、区别
唯一本质区别:线程安全。
StringBuffer因为每次操作都要获取锁,所以性能稍差;而StringBuilder没有锁的开销,速度更快。
这里有一个常见误解:很多人以为StringBuilder完全不安全,其实它只是在多线程同时操作时才会出问题。在单线程环境下,它非常可靠,而且比StringBuffer快。

三、怎么正确选择

选择非常简单,单线程就用StringBuilder,多线程共享就用StringBuffer。
1) 在实际应用中,绝大多数情况都是单线程的。比如在一个方法内部拼接字符串,或者在循环里构建日志信息,这些场景下StringBuilder是默认选择。
2) StringBuffer的使用场景比较有限,最常见的是多个线程同时向一个缓存区写入内容

四、常见的错误用法

最常见的一个错误是在循环内部创建StringBuilder对象:

for (int i = 0; i < 10000; i++) {
StringBuilder sb = new StringBuilder();
sb.append(i);
result = sb.toString();
}

这样每次循环都会创建一个新对象,完全失去了复用的意义。
正确做法是在循环外创建,循环内只调用append():

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append(i);
}
String result = sb.toString();

五、基础应用

当你写下这样的代码时:

String s = "Hello" + " " + "World";

编译器会在编译时自动将它优化为:

String s = new StringBuilder().append("Hello").append(" ").append("World").toString();

所以,少量拼接直接用+是可以的,编译器会帮你优化。但如果是在循环中拼接,就必须手动使用StringBuilder,因为编译器无法优化循环中的拼接操作。

六、总结

单线程拼字符串,用StringBuilder就可以,当多线程共享同一对象,才考虑StringBuffer。

posted @ 2026-06-21 22:00  Znkunft  阅读(4)  评论(0)    收藏  举报