选择stringbuffer而非stringbuilder是因为其所有公开方法均被synchronized修饰,天然线程安全;而stringbuilder无同步机制,多线程并发调用会导致数据错乱。

Java中用StringBuffer实现线程安全的Builder模式,核心在于利用StringBuffer自身的方法都是同步的这一特性,避免在Builder类中额外加锁,同时保持链式调用和可变状态的安全性。
为什么选择StringBuffer而不是StringBuilder
StringBuffer是线程安全的,所有公开方法(如append()、insert()、toString())都用synchronized修饰;而StringBuilder不是,多线程下直接使用会导致数据错乱。若Builder实例可能被多个线程共享并并发构建,StringBuffer就是更稳妥的选择。
Builder类的基本结构设计
Builder本身不需额外同步,只需内部持有StringBuffer字段,并让每个修改方法返回this以支持链式调用。注意:不能直接暴露StringBuffer引用,防止外部误操作破坏线程安全性。
- 构造器初始化一个空的
StringBuffer - 每个
addXxx()方法调用stringBuffer.append(...)后返回this -
build()方法调用stringBuffer.toString()返回最终字符串 - 避免在
build()后继续调用修改方法(可选:构建后置为不可变状态或抛异常)
一个简洁可用的示例
注意:该Builder实例本身是可变且非线程安全的“对象状态”,但只要每个线程操作自己的Builder实例,或通过正确同步共享实例,就能保证结果正确。
public class ThreadSafeStringBuilder {
private final StringBuffer buffer;
public ThreadSafeStringBuilder() {
this.buffer = new StringBuffer();
}
public ThreadSafeStringBuilder add(String s) {
buffer.append(s);
return this;
}
public ThreadSafeStringBuilder add(int i) {
buffer.append(i);
return this;
}
public String build() {
return buffer.toString();
}
}
用法示例:
ThreadSafeStringBuilder builder = new ThreadSafeStringBuilder();
String result = builder.add("Hello").add(" ").add("World").build(); // "Hello World"
实际并发使用的注意事项
即便用了StringBuffer,仍需明确Builder实例的生命周期和共享范围:
- 推荐每个线程创建独立Builder实例(最简单、无竞争)
- 若必须复用同一实例,需在外层同步(如用
synchronized块包裹构建逻辑) - 不要把Builder设为静态或单例并供多线程随意调用——这会引入竞争,即使内部用
StringBuffer也无法保证逻辑正确性 - 如果构建过程涉及复杂状态(如条件分支、多次重置),建议加简单标记(如
built标志位)防止重复构建
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











