synchronized 通过锁机制解决原子性、可见性、有序性:修饰实例方法锁 this,静态方法锁 class,代码块可指定锁对象;解锁刷新主存、加锁重读最新值;建立 happens-before 禁止重排序;误用非共享锁对象或读写不同步将导致失效。

synchronized 在保障多线程环境下代码执行正确性时,核心是解决三个关键问题:原子性、可见性和有序性。它不是万能锁,但恰当地使用能有效防止共享数据被破坏。
确保操作的原子性
多个线程并发修改同一变量(如自增 count++)时,该操作实际包含“读取→修改→写入”三步,非原子执行会导致中间状态丢失。synchronized 通过加锁机制,让被修饰的方法或代码块变成一个不可分割的执行单元。
- 修饰实例方法 → 锁住当前对象(this),同一对象的多个 synchronized 实例方法互斥
- 修饰静态方法 → 锁住类对象(Class),所有线程访问该类的 synchronized 静态方法时排队
- 修饰同步代码块 → 显式指定锁对象,可精细控制粒度,避免锁整个对象
保证变量修改的可见性
Java 内存模型中,线程有自己的工作内存,可能缓存变量副本。没有同步机制时,一个线程改了值,另一个线程未必立刻看到。synchronized 的解锁动作会强制将工作内存中修改过的变量刷新到主内存;加锁前则强制从主内存重新读取最新值。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 这意味着:线程 A 在 synchronized 块内修改了 sharedFlag = true,线程 B 进入同一把锁的 synchronized 块时,一定能读到 true
- 不依赖 volatile 或额外 flush 操作,天然满足 happens-before 规则
维持执行的有序性
编译器和处理器可能对指令重排序以优化性能,但在多线程下可能破坏逻辑依赖。synchronized 通过“锁规则”建立 happens-before 关系:一个线程对锁的解锁,happens-before 另一个线程对该锁的加锁。
- 这禁止了跨越锁边界的重排序,比如临界区内赋值语句不会被移到锁外
- 配合原子性和可见性,共同保障代码按预期顺序对其他线程生效
避免常见误用陷阱
作用再强,用错对象也白搭。关键在于锁对象是否真正共享且一致:
- 用 new Object() 作为锁对象 → 每次新建对象,锁不共享,完全失效
- 用 this 锁实例方法,但多线程操作的是不同实例 → 各自锁各自对象,互不影响
- 静态方法和实例方法混用同一资源,却分别用类锁和实例锁 → 实际未形成统一同步点
- 只同步写操作,不同步读操作 → 读线程仍可能看到过期值(需读也进入同一把锁)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










