线程安全总结
1.线程安全
1.1什么是线程安全
线程安全问题指的是当多个线程同时访问和操作共享资源(如变量、数据结构等)时,由于缺乏有效的同步控制,导致程序出现不可预期的错误或数据不一致的现象。其核心在于并发操作破坏了程序的正确性。
通俗来说 就是一段代码在多线程 并发执行后 出现bug
1.2 为什么会出现线程安全问题?
1. 竞态条件(Race Condition)
多个线程以不可预测的顺序执行,导致结果依赖于线程执行的时序。例如:两个线程同时读取一个变量并修改后写入,可能覆盖彼此的结果。
操作系统对于线程的调度是随机的 核心(抢占式执行)
2. 内存可见性问题
一个线程修改了共享变量,但另一个线程可能无法立即看到修改后的值(由于CPU缓存的存在)。
3. 指令重排序
CPU或编译器为了优化性能可能调整指令执行顺序,导致代码实际执行顺序与预期不符。
2.解决方案
2.1 加锁
synchronized 关键字
死锁
一旦代码触发死锁 程序就卡住了
原因:1 互斥性
2.不可剥夺/不可抢占
3.请求和保持
4.循环等待
解决死锁的方案:避免锁嵌套 解决三 约定加锁顺序 解决四
2.2 volatile
用于修饰变量 保证数据准确性
-
保证变量的可见性,即不同的线程看到的一个变量的值是相同的。
-
保证赋值操作的原子性,即使在多线程环境下,也不用担心线程安全问题或者数据不一致的问题。
-
禁止指令重排,即强制编译器按照程序顺序访问变量。
经典示例:计数器问题
public class Counter {
private int count = 0;
public void increment() {
count++; // 非原子操作:读取 → 修改 → 写入
}
public int getCount() { return count; }
}
当多个线程同时调用 `increment()` 时:
1. 线程A读取 `count=0`
2. 线程B也读取 `count=0`
3. 两者各自加1后写入,最终 `count=1`(正确结果应为2)