volatile 的优点:
轻量级: volatile 不需要依赖于操作系统线程调度,其操作由 CPU 的原子指令完成,开销比 synchronized 小。
简单易用: volatile 的语法简单,使用方便,不需要显式地获取和释放锁。
内存可见性保证: volatile 变量的读写操作具有原子性,可以保证内存可见性,即一个线程对共享变量的修改对其他线程立即可见。
volatile 的缺点:
不保证原子性: volatile 变量的单个读/写操作具有原子性,但类似于 volatile++ 这样的复合操作不具有原子性,需要其他机制保证。
无法防止竞争条件: volatile 无法防止多个线程同时访问共享资源时发生竞争条件,需要其他同步机制保证线程安全。
不能替代 synchronized: volatile 无法替代 synchronized 的所有功能,例如无法实现锁降级、条件变量等功能。
synchronized 的优点:
原子性: synchronized 保证了临界区代码的原子性,即多个线程不能同时进入临界区。
可见性: synchronized 保证了共享变量的可见性,即一个线程对共享变量的修改对其他线程立即可见。
排他性: synchronized 保证了临界区代码的排他性,即同一时刻只有一个线程能进入临界区。
功能丰富: synchronized 支持多种同步机制,例如重入锁、条件变量等,功能丰富。
synchronized 的缺点:
重量级: synchronized 需要依赖于操作系统线程调度,开销较大。
死锁风险: 使用 synchronized 时需要小心处理锁的获取和释放,否则容易发生死锁。
可读性差: synchronized 的语法较为复杂,可读性较差。
适用场景:
对于简单且不需要保证原子性的场景,推荐使用 volatile。 例如,控制台输出、计数器等。
对于需要保证原子性、可见性和排他性的场景,推荐使用 synchronized。 例如,共享数据的读写、并发控制等。
对于需要复杂同步控制功能的场景,推荐使用 ReentrantLock 等显示锁。
本文作者:whitebear
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!