volatile仅保障变量可见性与有序性但不保证原子性,synchronized则通过锁机制同时保障原子性、可见性与有序性;前者适用于状态标志等简单场景,后者适用于复合操作等需互斥控制的场景。

本质区别在于:volatile 是一种轻量级的内存可见性保障机制,只管“变量改了别人能不能立刻看到”,不干预执行流程;synchronized 是一种重量级的互斥同步机制,既管“看到”,也管“谁来改”和“怎么改”,通过锁控制临界区的独占执行。
作用粒度与范围不同
volatile 只能修饰变量,作用于单个字段的读写操作;它不锁定任何代码,也不限制线程调度。synchronized 可以修饰实例方法、静态方法或任意代码块,锁定的是对象(或类)级别的监视器,控制的是整段逻辑的串行执行。
- volatile 修饰的 flag,多个线程可同时读、同时写,只是每次读都强制从主内存取,每次写都强制刷回主内存
- synchronized 保护的 count++,同一时刻只允许一个线程进入,其他线程必须等待——哪怕只是读一个 int 值,也要排队
保证的并发特性不同
volatile 提供可见性和有序性(禁止指令重排序),但不保证原子性;synchronized 同时提供原子性、可见性和有序性。
- 对 volatile 变量执行 i++,仍会被拆成“读-改-写”三步,多线程下结果可能出错
- 用 synchronized 包裹 i++,整个操作变成不可分割的临界区,结果一定正确
- volatile 能让一个线程写的 running = false 立刻被另一个线程的 while 循环感知到;synchronized 在加锁时重载变量、解锁时刷新变量,同样实现可见,但代价是阻塞
线程行为与性能表现不同
volatile 不会引起线程阻塞,读写开销接近普通变量,适合高频读+低频写的场景;synchronized 会触发锁竞争、上下文切换甚至挂起唤醒,存在明显性能开销,但适用性更广。
- 状态标志位(如开关、中断信号)——首选 volatile
- 复合逻辑(如先查后改、累加计数、资源分配)——必须用 synchronized 或更高级的并发工具
- volatile 无法防止指令重排带来的逻辑错乱(例如对象未完全构造就被其他线程引用),而 synchronized 的锁边界天然形成内存屏障,能规避这类问题
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











