底层实现原理简述
ReentrantLock 的底层是基于 AQS (AbstractQueuedSynchronizer) 框架实现的。
核心状态 (state):AQS 内部维护了一个 volatile int state 变量。
state = 0:表示锁未被任何线程持有。
state > 0:表示锁已被持有,其值代表当前线程的重入次数。
同步队列:AQS 还维护了一个 FIFO 的双向队列(CLH 队列的变体),用于存放所有因获取锁失败而阻塞的线程。
工作流程:
当线程调用 lock() 时,会尝试通过 CAS (Compare-And-Swap) 操作将 state 从 0 修改为 1。
如果成功,则该线程获得锁,并将自己设置为独占线程。
如果失败(说明锁已被占用),则当前线程会被封装成一个 Node 节点,加入到同步队列的尾部,并被阻塞(park)。
当持有锁的线程调用 unlock() 时,state 会递减。当 state 变为 0 时,锁被释放,AQS 会唤醒队列头部的下一个线程,让它有机会重新尝试获取锁。

Synchronized
synchronized 是 Java 语言内置的关键字,使用简单
在java 1.6之后 做了优化,锁升级策略,升级步骤为:无锁 -> 偏向锁 -> 自旋锁 -> 重量锁。

无锁:对象未被任何线程锁定。
偏向锁:当只有一个线程访问同步块时,JVM 会将该线程 ID 记录在对象头中,下次该线程进入时无需任何同步操作,性能极高。
轻量级锁:当有另一个线程尝试竞争锁时,偏向锁升级为轻量级锁。线程会通过 CAS(自旋)的方式尝试获取锁,避免了线程阻塞和上下文切换的开销。
重量级锁:cas自选十次后,当竞争激烈,自旋消耗过大时,轻量级锁会升级为重量级锁。此时,未能获取锁的线程会被阻塞,进入等待队列,由操作系统负责调度,开销较大。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐