当前位置: 首页 > news >正文

20250214 随笔 线程安全 线程不安全

1. 什么是线程安全 & 线程不安全?

  • 线程安全(Thread-Safe):在多线程环境下访问同一个对象时,不会产生数据竞争、不会出现数据不一致的问题
  • 线程不安全(Not Thread-Safe):在多线程环境下,多个线程同时访问同一个对象可能会导致数据不一致,需要手动加锁或者使用线程安全的方式来操作。

2. StringBuffer 线程安全,StringBuilder 线程不安全

💡 主要区别在于

  • StringBuffer 是线程安全的,因为它的很多方法都加了 synchronized 关键字。
  • StringBuilder 是线程不安全的,因为它没有加 synchronized,多线程访问时可能会出现数据不一致问题。
🔹 StringBuffer(线程安全)
StringBuffer sb = new StringBuffer("Hello");

// 多线程修改同一个 StringBuffer 对象
Thread t1 = new Thread(() -> {
    sb.append(" World");
});

Thread t2 = new Thread(() -> {
    sb.append(" Java");
});

t1.start();
t2.start();
t1.join();
t2.join();

System.out.println(sb); // 结果是可预测的,因为 append() 方法是同步的

🔹 StringBuffer 内部的方法(如 append()insert())都加了 synchronized,保证了 同一时刻只有一个线程可以修改 StringBuffer 对象,所以它是 线程安全的


🔹 StringBuilder(线程不安全)
StringBuilder sb = new StringBuilder("Hello");

// 多线程修改 StringBuilder
Thread t1 = new Thread(() -> {
    sb.append(" World");
});

Thread t2 = new Thread(() -> {
    sb.append(" Java");
});

t1.start();
t2.start();
t1.join();
t2.join();

System.out.println(sb); // 可能输出 Hello World Java,也可能出现乱码

🔹 StringBuilder 没有 synchronized,多个线程同时访问时,可能会发生数据错乱,如

Hello WorldJava
Hello JavaWorld
Hello WJavorld

💡 因为多个线程可以同时修改 StringBuilder,导致数据写入时发生竞争,出现不可预测的情况


3. StringBuffer & StringBuilder 内部实现区别

📌 StringBuffer 使用 synchronized,保证线程安全

public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

🔹 append() 方法使用了 synchronized,意味着同一时刻只有一个线程能执行它,这样就保证了线程安全

📌 StringBuilder 没有 synchronized,线程不安全

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

🔹 append() 方法没有 synchronized,多个线程同时修改时会产生数据竞争


4. 线程安全 vs 线程不安全,如何选择?

特性StringBuffer(线程安全)StringBuilder(线程不安全)
是否线程安全✅ 是❌ 不是
是否使用 synchronized✅ 是(同步)❌ 不是(无锁)
适用场景多线程环境(如 Web 服务器、并发任务)单线程环境(普通字符串拼接)
性能较慢(加锁有性能损耗)更快(无锁操作)
替代方案StringBuilder + synchronizedLock适用于单线程,性能更好

💡 如何选择?

  • 单线程:使用 StringBuilder,性能更高
  • 多线程:使用 StringBuffer,防止数据竞争
  • 多线程但性能要求高?可以使用 StringBuilder + synchronizedLock

5. 线程安全一定好?为什么有线程不安全的 StringBuilder?

💡 线程安全的代价是“性能下降”

  • StringBuffer 每次操作都需要 synchronized,即使单线程也会加锁,影响性能
  • StringBuilder 不加锁,在单线程下性能更快,适合大多数情况

示例:StringBuffer 在单线程下的性能劣势

long startTime = System.nanoTime();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 100000; i++) {
    sb.append("Java");
}
long endTime = System.nanoTime();
System.out.println("StringBuffer 时间:" + (endTime - startTime) + " ns");

对比:StringBuilder 在单线程下的性能

long startTime = System.nanoTime();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100000; i++) {
    sb.append("Java");
}
long endTime = System.nanoTime();
System.out.println("StringBuilder 时间:" + (endTime - startTime) + " ns");

💡 单线程下,StringBuilder 速度明显更快,因为它没有加锁!


6. 线程安全 & 线程不安全的选择策略

场景推荐选择
单线程字符串拼接StringBuilder
多线程共享字符串对象StringBuffer
多线程 + 高性能要求StringBuilder + synchronized
不可变字符串(不修改)String

7. 结论

StringBuffer 是线程安全的,因为它的方法加了 synchronized,适用于多线程环境
StringBuilder 是线程不安全的,但性能更好,适用于单线程环境
线程安全不一定好,StringBuffer 虽然安全,但单线程下性能比 StringBuilder
如果多线程但又想提升性能,可以使用 StringBuilder + synchronized 进行手动控制

💡 面试高频考点

  1. StringBuffer 和 StringBuilder 的区别?
  2. 为什么 StringBuilder 是线程不安全的?
  3. 如何让 StringBuilder 变成线程安全的? ✅ 答案:加 synchronized,或者使用 Lock
  4. 什么时候用 StringBuffer?什么时候用 StringBuilder? ✅ 单线程用 StringBuilder,多线程用 StringBuffer

相关文章:

  • 解锁 DeepSeek 超强能力:蓝耘智算平台搭建实战秘籍
  • 跟着李沐老师学习深度学习(八)
  • 详细介绍:使用 XMLHttpRequest 进行数据提交(完成用户注册功能)
  • Docker 部署 Nacos (图文并茂超详细)
  • SpringBoot+shardingsphere实现按月分表功能
  • python实现YouTube关键词爬虫(2025/02/11)
  • 【Spring】Spring MVC入门(二)
  • Linux第107步_Linux之PCF8563实验
  • java05(类、泛型、JVM、线程)---java八股
  • 前端与浏览器安全知识详解
  • 程序员升级进阶之路
  • spring security 超详细使用教程(接入springboot、前后端分离)
  • [创业之路-299]:图解金融体系结构
  • Linux 文件系统:恢复已删除文件的挑战
  • 【大模型】阿里云百炼平台对接DeepSeek-R1大模型使用详解
  • 【深度强化学习】Actor-Critic 算法
  • 一个根据输入内容过滤下拉选的组件
  • 网络编程-
  • 设计模式Python版 命令模式(下)
  • Keysight E5071C (Agilent) 网络分析仪的特性和规格
  • 西域都护府博物馆今日在新疆轮台县开馆
  • 出走的苏敏阿姨一路走到了戛纳,这块红毯因她而多元
  • 病愈出院、跳大神消灾也办酒,新华每日电讯:农村滥办酒席何时休
  • 浙江演艺集团7部作品组团来沪,今夏开启首届上海演出季
  • 混乱的5天:俄乌和谈如何从充满希望走向“卡壳”
  • 清雪车司机未拉手刹下车导致溜车被撞亡,事故调查报告发布