ReentrantLock 与 AQS 的原理与应用
2023-10-05 07:21:23
深入浅出:ReentrantLock 和 AQS 原理揭秘
可重入锁的本质:ReentrantLock
ReentrantLock 是 Java 中鼎鼎大名的可重入锁,它让一个线程可以多次获取同一把锁,杜绝了死锁的风险。它还有一个兄弟——AQS(AbstractQueuedSynchronizer) ,它是 ReentrantLock 背后的强大引擎,为多种同步组件奠定了基础。
同步核心:AQS
AQS 的核心是state 变量,它是一个整数,记录着锁的状态。当 state 为 0,锁是空闲的;当 state 为 1,锁被一个线程独占;当 state 大于 1,说明锁被多个线程共享。
AQS 巧妙地利用CAS(Compare-And-Swap)机制 来更新 state 变量。CAS 是一种乐观锁技术,它比较一个变量的预期值和实际值,如果相等,就将实际值替换为新值。当一个线程试图获取锁时,它使用 CAS 将 state 从 0 替换为 1。如果成功,线程就获得了锁;如果失败,说明锁已被其他线程占用,当前线程会加入等待队列。
AQS 还维护着一个FIFO(先进先出)队列 ,用于管理等待获取锁的线程。当锁释放时,AQS 会唤醒队列中的第一个线程,授予它锁。
ReentrantLock 的妙用
ReentrantLock 广泛应用于 Java 并发编程,它可以实现多种同步场景:
- 排他锁: 使用 ReentrantLock,你可以保护临界区,确保同一时间只有一个线程执行该代码块。
- 读写锁: ReentrantLock 支持读写锁,它允许多个线程同时读共享资源,但只允许一个线程写共享资源。
- 可中断锁: ReentrantLock 支持中断机制,当线程等待锁时,可以被其他线程中断。
- 可超时锁: ReentrantLock 支持超时机制,如果线程等待锁的时间超过指定时间,会自动放弃锁并抛出异常。
其他 AQS 同步器
除了 ReentrantLock,AQS 还提供了其他同步器实现,包括:
- Semaphore: 用于限制同时访问资源的线程数量。
- CountDownLatch: 用于等待一组事件完成。
- CyclicBarrier: 用于等待一组线程到达某个屏障。
- Exchanger: 用于在两个线程之间交换对象。
常见问题解答
-
什么是 ReentrantLock?
ReentrantLock 是 Java 中一种可重入锁,它允许同一个线程多次获取同一把锁。 -
什么是 AQS?
AQS 是 Java 中一个抽象同步框架,它为 ReentrantLock 等同步组件提供基础。 -
CAS 是什么?
CAS 是一种乐观锁机制,它比较一个变量的预期值和实际值,如果相等,就将实际值替换为新值。 -
ReentrantLock 如何实现可重入性?
ReentrantLock 通过维护一个计数器来实现可重入性,每当一个线程获取锁时,计数器加 1;当线程释放锁时,计数器减 1。只有当计数器为 0 时,锁才被真正释放。 -
AQS 如何确保锁的公平性?
AQS 提供了两种锁的实现:公平锁和非公平锁。公平锁保证线程获取锁的顺序与请求锁的顺序一致,而非公平锁则不保证。
总结
ReentrantLock 和 AQS 是 Java 并发编程的基石。理解它们的原理至关重要,它们为构建高效、可靠的并发程序提供了强大的基础。掌握这些知识,你将成为 Java 并发编程领域的弄潮儿,挥洒自如,让代码并发飞扬!