volatile 能保证什么不能保证什么
volatile 和 synchronized 经常被拿来比较,但它们解决的问题不一样。很多人误以为 volatile 能保证原子性,其实它只能保证可见性和禁止指令重排。本文从内存模型角度说明 volatile 的作用和局限性。
先建立一个最小案例
并发问题不要一开始就上复杂业务。可以先准备一个计数器场景:
class Counter { |
这段代码在单线程里没有问题,但多线程同时调用 add() 时,count++ 不是原子操作,结果可能比预期小。
正确处理思路
如果只是简单计数,可以用 AtomicInteger:
class Counter { |
如果临界区里有多步业务逻辑,可以考虑 synchronized 或 ReentrantLock。选择时不要只看性能,先看代码是否清晰、锁范围是否足够小、异常时是否能释放锁。
排查建议
线上并发问题通常不稳定复现。可以先看日志里是否有重复请求、状态覆盖、库存扣减异常,再用压测或单元测试构造并发场景。
核心要点
volatile 保证可见性:一个线程的修改对其他线程立即可见
volatile 禁止指令重排:确保指令按照代码顺序执行
volatile 不保证原子性:复合操作仍然需要同步
volatile 适合作为状态标志,不适合作为计数器
总结
volatile 是一个轻量级的同步手段,适用于特定场景。在实际项目中,需要根据需求选择合适的同步方式,不要过度依赖 volatile。