关于Synchronized和ReentrantLock

锁优化机制

术语 定义
偏向锁(Biased Locking) JVM 锁优化策略。当同步块持续被同一线程获取时,锁对象头中的 Mark Word 会记录该线程 ID,后续该线程进入同步块无需 CAS 操作,仅比较线程 ID 即可。适用于无竞争场景,消除无竞争同步的原子操作开销。JDK 15 起默认禁用。
轻量级锁(Lightweight Locking) 当偏向锁遇到竞争时,JVM 将对象头替换为指向线程栈中 Lock Record 的指针,通过 CAS 自旋获取锁。避免线程阻塞和内核态切换,适用于线程交替执行、竞争短暂的场景。
自适应自旋(Adaptive Spinning) 动态调整自旋等待时间的策略。JVM 根据前一次自旋获取锁的成功率及持有时间,智能预测本次自旋次数,成功率高则增加自旋,反之直接挂起线程,平衡 CPU 消耗与响应延迟。

锁类型

术语 定义
synchronized Java 语言层面的内置同步机制,基于 Monitor(监视器)实现。通过 monitorenter / monitorexit 字节码指令操作对象头的 Mark Word,依赖 JVM 进行锁升级和优化。
ReentrantLock java.util.concurrent.locks 包提供的显式可重入互斥锁,基于 AQS(AbstractQueuedSynchronizer)框架实现。需手动调用 lock() / unlock(),支持公平锁、可中断、超时获取、条件变量等扩展语义。

JVM 编译与运行时优化

术语 定义
锁消除(Lock Elision) 逃逸分析(Escape Analysis)的应用。JIT 编译器判定某同步块的对象引用不会逃逸出当前线程(即无共享访问),则直接移除同步代码,消除锁开销。
锁粗化(Lock Coarsening) JIT 编译器将相邻的多个连续同步块(通常由循环展开或频繁加锁解锁导致)合并为范围更大的单一同步区域,减少重复的加锁解锁操作次数,降低同步开销。
JIT 编译(Just-In-Time Compilation) JVM 将热点字节码动态编译为本地机器码的执行方式。通过方法调用计数器与回边计数器触发编译,使高频代码以接近原生性能运行,并为深度优化(如内联、逃逸分析)提供基础。
内存布局(Memory Layout) 对象在堆内存中的结构化存储方式。synchronized 的锁状态直接编码在对象头(Object Header)的 Mark Word 中,而 ReentrantLock 作为独立对象实例,需额外的对象头开销和指针解引用,缓存局部性更差。

并发基础概念

术语 定义
对象头(Object Header) HotSpot 虚拟机中对象在堆中的元数据区域,包含 Mark Word(存储哈希码、GC 年龄、锁状态标志等)和类型指针(Klass Pointer)。锁升级过程中,Mark Word 的 64 位/32 位数据会动态重用以存储锁状态信息。
Mark Word 对象头的第一部分,用于存储对象自身的运行时数据。在不同锁状态下,其位布局动态变化:无锁时存哈希码和分代年龄;偏向锁时存线程 ID;轻量级锁时存指向 Lock Record 的指针;重量级锁时存指向 Monitor 的指针。
Monitor(监视器) 操作系统层面的同步机制实现,对应 ObjectMonitor 结构。包含 _owner(持有线程)、_EntryList(阻塞队列)、_WaitSet(等待队列)等字段。依赖操作系统互斥量(mutex)和条件变量(condition variable),涉及用户态与内核态切换,开销最大。
CAS(Compare-And-Swap) 原子操作指令,通过比较内存值与预期值,若相等则更新为新值。轻量级锁和 AQS 框架的核心原语,属于无锁算法(Lock-Free)的基础,但存在 ABA 问题和自旋开销。
AQS(AbstractQueuedSynchronizer) java.util.concurrent 包的核心抽象框架,提供基于 FIFO 等待队列的阻塞式锁和同步器基础。ReentrantLockSemaphoreCountDownLatch 等均基于 AQS 实现,通过 CAS 管理 state 状态和双向链表队列。

线程状态与调度

术语 定义
内核态切换(Context Switch) 线程从用户态进入内核态(或反之)的 CPU 特权级转换。重量级锁竞争失败时,线程调用 pthread_mutex_lock 进入内核阻塞,触发上下文切换,保存/恢复寄存器状态,代价高昂(通常微秒级)。
用户态自旋(User-Level Spinning) 线程在用户空间通过循环空转(while + pause 指令)等待锁释放,不释放 CPU 时间片也不陷入内核。利用多核 CPU 的缓存一致性协议监听锁状态变化,避免上下文切换,但持续占用 CPU 周期。

权威参考

术语 定义
Doug Lea Java 并发编程领域核心人物,纽约州立大学奥斯威戈分校计算机科学教授。主导设计 java.util.concurrent(JSR 166)包,包括 AQS 框架、原子类、并发集合等,其著作《Concurrent Programming in Java》为并发经典教材。
posted @ 2026-07-20 15:11  ruo_feng  阅读(9)  评论(0)    收藏  举报
-->