scala 的 `synchronized` 并非语法关键字,而是 `anyref` 上定义的普通方法,支持显式锁对象、隐式 `this` 锁及中缀调用形式,三者语义一致但锁作用域和可读性不同。
在 Scala 中,synchronized 是 AnyRef(即 JVM 中的 java.lang.Object)的一个实例方法,其签名等价于:
final def synchronized[T](body: => T): T
这意味着它本质上是“对当前对象加锁后执行代码块”,而非 Java 中的 synchronized 语句(后者是 JVM 指令级语法)。因此,所有 synchronized 调用最终都归结为 对某个具体对象执行 monitor enter/exit —— 这正是 JVM 同步的基础。
三种常见写法及其等价关系
| 写法 | 示例 | 实际锁对象 | 说明 |
|---|---|---|---|
| 隐式 this 锁 | synchronized { … } | 当前 this 实例 | 等价于 this.synchronized { … },适用于保护本对象内部状态 |
| 显式对象锁 | lock.synchronized { … } | lock 实例(如 new Object()) | 推荐方式:避免锁粒度粗、防止外部误锁 this,提升并发安全性 |
| 中缀调用(省略点) | lock synchronized { … } | lock 实例 | Scala 中缀语法糖,仅当方法名不含参数且为单参数时允许省略 . 和括号;语义完全等价于 lock.synchronized { … } |
✅ 所有形式均调用同一方法,底层行为完全一致:JVM 对指定对象执行 monitorenter/monitorexit。