Java 中 StringBuffer 的内部状态如何随并发操作改变

阿浩大大_2201

阿浩大大_2201

2026-06-24

129人浏览

原创

stringbuffer线程安全靠每个public修改方法加synchronized修饰,锁对象为this,确保count和value的更新原子可见;但多步操作如if-then-append需外层synchronized保护。

java 中 stringbuffer 的内部状态如何随并发操作改变

StringBuffer 的内部状态在并发操作下不会“错乱”,但它的变化是受锁保护的、逐方法原子的,不是业务逻辑连贯的——也就是说,单个 append 或 insert 能安全执行完,但 if-then-append 这类多步判断+修改就可能出错。

底层结构:char[] + count + 同步锁

StringBuffer 继承自 AbstractStringBuilder,核心字段只有三个:

  • char[] value:真正存字符的数组,可动态扩容
  • int count:当前有效字符长度(不是数组长度)
  • 对象级 this 锁:所有 public 修改方法都 synchronized(this)

每次调用 append、insert、delete 等方法时,JVM 先获取该实例的 monitor 锁,再更新 value 和 count;toString() 也同步,还会维护一个 toStringCache(JDK 9+),但这个缓存本身也是被锁保护的,高并发下易失效,反而增加开销。

并发下状态变化的真实表现

多个线程同时调用同一 StringBuffer 实例的方法时,状态改变遵循以下规律:

  • 任意时刻最多一个线程能进入 append(),其他线程阻塞等待——count 和 value 的修改是原子完成的
  • 线程 A 执行 sb.append("a") 后,value 数组和 count 都已更新,且对其他线程可见(因 synchronized 的内存语义)
  • 但若线程 A 先调用 sb.length() 得到 5,线程 B 紧接着 append("x") 把 count 改成 6,A 再调用 sb.append("y")——结果是 "....xy",而非预期的仅在长度不足时追加
  • toString() 返回的是新 String 对象,后续对该 String 的任何操作(如 substring)不再受 StringBuffer 锁保护,也不影响其内部状态

扩容时的状态跃变

当 append 导致 char[] 不够用,StringBuffer 会触发扩容(通常是 oldCapacity * 2 + 2):

  • 整个扩容过程(new char[]、System.arraycopy、赋值给 value、更新 count)都在 synchronized 块内完成
  • 扩容期间其他线程完全阻塞,不会看到“半新半旧”的数组状态
  • 但频繁扩容会加剧锁竞争——建议初始化时指定合理容量,如 new StringBuffer(1024)

注意:同步不等于业务一致

StringBuffer 保证的是每个方法调用的执行不交错,不是整个业务流程的线程安全。例如:

  • 错误写法:if (sb.length() == 0) sb.append("init"); —— length() 和 append() 是两次独立加锁操作,中间可能被其他线程插入内容
  • 正确做法:synchronized(sb) { if (sb.length() == 0) sb.append("init"); } —— 显式扩大临界区,把判断和修改包进同一把锁

本质上,StringBuffer 的并发安全性是“方法级”的,不是“场景级”的。它兜得住数据结构不崩,兜不住你写的逻辑漏洞。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

10517

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7642

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6672

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1144

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

928

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1376

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2769

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20071

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1235

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习