synchronized保证原子性、可见性和有序性,适用于代码块或方法加锁,基于监视器实现,性能开销较大;volatile仅保证可见性和有序性,用于变量修饰,依赖内存屏障,不阻塞线程但不保证原子性;两者互补,按需选用。

synchronized 和 volatile 都是 Java 中用于处理多线程并发问题的关键字,但它们的作用和使用场景有明显区别。
synchronized 保证了原子性、可见性和有序性。它通过加锁机制确保同一时刻只有一个线程可以执行被 synchronized 修饰的代码块或方法,从而防止多个线程同时修改共享数据导致的问题。
volatile 只保证可见性和有序性,不保证原子性。当一个变量被声明为 volatile,任何线程对它的修改都会立即刷新到主内存中,其他线程读取时也能立刻看到最新值。但它不能防止多个线程同时进行读-改-写操作带来的竞态条件。
synchronized 可以修饰代码块、实例方法和静态方法,需要指定一个锁对象(对于实例方法是 this,静态方法是类对象)。
立即学习“Java免费学习笔记(深入)”;
volatile 只能修饰变量,不能修饰方法或代码块。
synchronized 是基于 JVM 的监视器锁(Monitor Lock)实现的,底层依赖操作系统的互斥量,属于重量级同步机制,但在 JDK 1.6 之后引入了偏向锁、轻量级锁等优化,性能已有大幅提升。
volatile 的实现依赖于内存屏障(Memory Barrier),在变量读写前后插入特定指令,确保变量的修改能及时同步到主内存,并禁止指令重排序。
synchronized 在发生竞争时可能导致线程阻塞,上下文切换开销较大,但无竞争时经过优化后成本较低。
volatile 不会引起线程阻塞,访问效率高,但由于每次读写都直接操作主内存,无法利用 CPU 缓存优势,频繁访问可能影响性能。
例如:用 volatile 修饰一个 boolean 标志位用来控制线程运行状态是合适的;但如果要对一个计数器进行自增操作(i++),即使变量是 volatile 的,也无法保证操作的原子性,必须使用 synchronized 或 AtomicInteger 等原子类。
基本上就这些。根据需求选择:需要原子性就用 synchronized 或原子类,只需要通知状态变化可用 volatile。两者不是替代关系,而是互补。
以上就是Java中synchronized 和 volatile 的区别是什么?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号