Java中StringBuilder和StringBuffer的区别

Java中StringBuilder和StringBuffer的区别

技术背景

在Java编程里,字符串处理是常见操作。String类对象是不可变的,每次对String对象进行修改都会创建新的String对象,这在频繁修改字符串时会消耗大量内存和性能。为解决此问题,Java提供了StringBufferStringBuilder类,它们都是可变的字符序列。

实现步骤

1. 基本使用

1
2
3
4
5
6
7
8
9
// 使用StringBuffer
StringBuffer stringBuffer = new StringBuffer("Hello");
stringBuffer.append(" World");
System.out.println(stringBuffer.toString());

// 使用StringBuilder
StringBuilder stringBuilder = new StringBuilder("Hello");
stringBuilder.append(" World");
System.out.println(stringBuilder.toString());

2. 多线程环境下使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
// 使用StringBuffer
StringBuffer stringBuffer = new StringBuffer();
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
executorService.execute(() -> {
for (int j = 0; j < 1000; j++) {
stringBuffer.append("a");
}
});
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.MINUTES);
System.out.println("StringBuffer length: " + stringBuffer.length());

// 使用StringBuilder
StringBuilder stringBuilder = new StringBuilder();
executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
executorService.execute(() -> {
for (int j = 0; j < 1000; j++) {
stringBuilder.append("a");
}
});
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.MINUTES);
System.out.println("StringBuilder length: " + stringBuilder.length());
}
}

核心代码

StringBuffer核心方法(部分)

1
2
3
4
5
6
7
8
9
10
11
public class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence {
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核心方法(部分)

1
2
3
4
5
6
7
8
9
10
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence {
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}

public StringBuilder append(String str) {
super.append(str);
return this;
}
}

最佳实践

  • 单线程环境:若代码仅在单线程环境运行,推荐使用StringBuilder,因其不进行同步操作,性能更佳。
1
2
3
4
5
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++) {
sb.append(i);
}
String result = sb.toString();
  • 多线程环境:若代码在多线程环境运行,且多个线程会同时访问和修改字符串,应使用StringBuffer
1
2
3
4
5
6
7
8
9
10
StringBuffer sb = new StringBuffer();
Runnable task = () -> {
for (int i = 0; i < 100; i++) {
sb.append(i);
}
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();

常见问题

1. StringBuffer是否绝对线程安全?

StringBuffer的单个方法是线程安全的,但如果涉及多个操作的组合,仍需外部同步。例如,先调用append再调用toString,在多线程环境下可能出现问题。

2. 性能差异是否显著?

在单线程环境下,StringBuilder性能通常优于StringBuffer,因为StringBuffer的同步操作会带来一定性能开销。但在某些JVM优化场景下,两者性能差异可能不明显。在多线程环境下,若使用StringBuilder不进行同步,可能会导致数据不一致问题。


Java中StringBuilder和StringBuffer的区别
https://119291.xyz/posts/2025-04-27.difference-between-stringbuilder-and-stringbuffer-in-java/
作者
ww
发布于
2025年4月27日
许可协议