StringBuilder 与 StringBuffer的区别

一、线程安全

StringBuilder线程不安全的,StringBuffer线程安全

StringBuffer(线程安全)

java 复制代码
public class StringBuffer extends AbstractStringBuilder {
    
    // 所有修改方法都加 synchronized 锁
    public synchronized StringBuffer append(String str) {
        super.append(str);
        return this;
    }
    
    public synchronized int length() {
        return count;
    }
    
    public synchronized void setCharAt(int index, char ch) {
        // ...
    }
}

StringBuilder(非线程安全)

scala 复制代码
public class StringBuilder extends AbstractStringBuilder {
    
    // 无 synchronized 修饰
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
    
    public int length() {
        return count;
    }
}

二、继承关系

dart 复制代码
java.lang.Object
2    └── java.lang.AbstractStringBuilder
3            ├── java.lang.StringBuilder
4            └── java.lang.StringBuffer

两者都继承自 AbstractStringBuilder,共享大部分底层实现代码

三、核心字段(AbstractStringBuilder)

java 复制代码
abstract class AbstractStringBuilder implements Appendable, CharSequence {
2    // 存储字符的数组
3    char[] value;
4    
5    // 当前已使用的字符数量
6    int count;
7    
8    // ...其他方法
9}

注意 :JDK 9+ 之后,String 改用 byte[] + 编码标记(Compact Strings),但 StringBuilder/StringBuffer 仍主要使用 char[]

四、扩容机制(核心原理)

scss 复制代码
// AbstractStringBuilder 中的扩容逻辑
private void expandCapacity(int minimumCapacity) {
    // 新容量 = 原容量 × 2 + 2
    int newCapacity = (value.length + 1) * 2;
    
    // 如果新容量仍不够,则使用最小需求容量
    if (newCapacity < minimumCapacity) {
        newCapacity = minimumCapacity;
    }
    
    // 处理溢出情况
    if (newCapacity < 0) {
        if (minimumCapacity < 0) {
            throw new OutOfMemoryError();
        }
        newCapacity = Integer.MAX_VALUE;
    }
    
    // 创建新数组并复制
    value = Arrays.copyOf(value, newCapacity);
}

扩容规则

场景

扩容策略

默认构造

初始容量 16

容量不足

newCapacity = (oldCapacity + 1) * 2

指定容量构造

初始容量 = 指定值

五、性能对比测试

操作

String

StringBuffer

StringBuilder

10万次拼接

~3000-5000ms

~15-30ms

~10-20ms

原因

每次创建新对象

同步锁开销

无锁开销

六、源码核心差异总结

维度

StringBuffer

StringBuilder

类修饰

final class

final class

继承

AbstractStringBuilder

AbstractStringBuilder

方法修饰

synchronized

无同步

底层数组

char[] value

char[] value

扩容公式

(oldCapacity + 1) * 2

(oldCapacity + 1) * 2

默认容量

16

16

序列化

实现 Serializable

实现 Serializable

七、深度理解

  1. 为什么不安全?

    • StringBuilder 的 countvalue 在多线程下可能被同时修改,导致数据不一致
  2. 为什么性能好?

    • 避免了 synchronized 的锁竞争和上下文切换开销
  3. 最佳实践

    go 复制代码
    // ✅ 推荐:预估容量,减少扩容
    StringBuilder sb = new StringBuilder(256);
    
    // ✅ 推荐:链式调用
    sb.append("Hello").append(" ").append("World");
    
    // ❌ 避免:频繁扩容
    StringBuilder sb = new StringBuilder(); // 会多次扩容
相关推荐
赵广陆14 小时前
企业实战:Markdown图片检索
android·java·开发语言
C++、Java和Python的菜鸟14 小时前
第3章 从0开始用若依
java·开发语言
小妖66614 小时前
设置了 box-sizing: border-box; 不管用,下边框还是被挤压没了
前端·css·html
Json____14 小时前
五金制品行业-企业官网源码
java·大数据·数据库·企业站·wwwoop.com
雪隐15 小时前
个人电脑玩AI-16让5060 Ti给你打工——5060Ti 16G 跑 MiniMax-Music-3:从下载到 60s 出歌的全流程
前端·人工智能·后端
counting money16 小时前
Spring AI Alibaba 从入门到实战:构建企业级 AI 应用
java·人工智能·spring
CAD老兵16 小时前
让 AI Coding Agent 直接访问 CAD 文档:GitMCP 实战指南
前端·人工智能·github
原野池予16 小时前
深入Java集合框架:数组与List互转底层原理剖析(JDK 8)
java·数据结构·list
程序员鱼皮16 小时前
DeepSeek Harness 最新邪修曝光!被吹成核弹的极简模式,真的夯吗?
前端·后端·ai编程
无己心16 小时前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节