synchronized 是 Java 基于 Monitor 实现的可重入独占锁,保障原子性、可见性、有序性;分修饰实例方法(锁 this)、静态方法(锁 Class)、同步代码块(显式指定锁对象)三种用法,底层对应 ACC_SYNCHRONIZED 标志或 monitorenter/monitorexit 指令,支持锁升级,但不支持中断、超时与公平策略。
synchronized 是 Java 内置的线程同步机制,用来保障多线程环境下临界区代码的原子性、可见性和有序性。它本质是基于对象监视器(Monitor)实现的可重入独占锁,用法简单但底层逻辑清晰。
关键不在“怎么写”,而在于“锁住谁”——锁对象决定了竞争范围:
this(当前对象实例)。不同实例之间互不影响,同一实例的多个 synchronized 实例方法串行执行。Class 对象(如 MyClass.class)。所有该类的实例共享这一把锁,适用于控制类级别资源访问。synchronized(obj) { ... }。粒度更细,灵活性高,推荐用于仅需保护部分逻辑的场景。编译后,synchronized 的实现分两类:
ACC_SYNCHRONIZED 标志。JVM 执行时自动检查该标志,进入前尝试获取 Monitor,退出时自动释放。monitorenter 和 monitorexit 两条字节码指令控制。每进入一次,Monitor 的计数器 +1;每退出一次,计数器 -1;计数器归零时锁才真正释放。每个 Java 对象头(Mark Word)都关联一个 Monitor,其状态会随竞争情况在无锁、偏向锁、轻量级锁、重量级锁之间升级。
synchronized 提供三大保障:
但它不是万能的:无法中断等待中的线程、不支持超时获取、默认非公平、也无法像 ReentrantLock 那样灵活绑定多个条件队列(Condition)。
String、常量或全局容器等可能被外部共享的对象;java.util.concurrent.locks.Reentran
tLock;