Java 6 引入锁优化机制,锁状态从无锁 → 偏向锁 → 轻量级锁 → 重量级锁单向升级,核心目标:减少无竞争/低竞争场景的同步开销。
| 锁类型 | 适用场景 | 核心机制 | 优缺点 |
|---|---|---|---|
| 无锁 | 单线程/线程局部 | 无同步 | 最高性能,无安全保障 |
| 偏向锁 | 无竞争/单线程重复获取 | CAS 设置线程 ID 到 Mark Word,后续直接比对 | 单线程极快;竞争时撤销开销大 |
| 轻量级锁 | 低竞争/短临界区 | CAS 将 Mark Word 指向栈帧 Lock Record | 无阻塞,自旋消耗 CPU |
| 重量级锁 | 高竞争/长临界区 | ObjectMonitor 监视器,OS 线程阻塞/唤醒 | 性能最低,但吞吐稳定 |
-XX:+UseBiasedLocking # 默认开启 -XX:BiasedLockingStartupDelay=4000 # 延迟 4s 启动,避免启动期竞争
实战验证:Vector 添加 1000 万元素,开启偏向锁耗时 ~300ms,关闭 ~800ms。禁用场景:高竞争环境(如连接池、并发队列),频繁撤销反而降性能。
线程栈帧分配 Lock Record,CAS 将对象头 Mark Word 指向它。成功则持有锁,失败则膨胀为重量级锁。关键点:displaced_header 备份原 Mark Word,解锁时 CAS 恢复。
ObjectMonitor 结构:_EntryList(等待队列)、_WaitSet(wait 集合)、_owner(持有线程)。涉及用户态/内核态切换,上下文切换开销大。
-XX:+UseSpinning # JDK 6 开启自旋 -XX:PreBlockSpin=10 # 自旋次数(JDK 7+ 废弃,JVM 自适应调整)
适用性判断:
monitor 或 thread -b 定位高竞争锁,优化算法/数据结构(如减少锁范围、用 ConcurrentHashMap 替代 synchronized Map)理解锁升级机制不是为了手动调参,而是建立同步开销的量级认知:无锁 < 偏向 < 轻量级 < 重量级。真正的高性能并发,源于设计层面减少共享可变状态,而非微调锁参数。