返回

ReentrantLock 与 AQS 的原理与应用

Android

深入浅出: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: 用于在两个线程之间交换对象。

常见问题解答

  1. 什么是 ReentrantLock?
    ReentrantLock 是 Java 中一种可重入锁,它允许同一个线程多次获取同一把锁。

  2. 什么是 AQS?
    AQS 是 Java 中一个抽象同步框架,它为 ReentrantLock 等同步组件提供基础。

  3. CAS 是什么?
    CAS 是一种乐观锁机制,它比较一个变量的预期值和实际值,如果相等,就将实际值替换为新值。

  4. ReentrantLock 如何实现可重入性?
    ReentrantLock 通过维护一个计数器来实现可重入性,每当一个线程获取锁时,计数器加 1;当线程释放锁时,计数器减 1。只有当计数器为 0 时,锁才被真正释放。

  5. AQS 如何确保锁的公平性?
    AQS 提供了两种锁的实现:公平锁和非公平锁。公平锁保证线程获取锁的顺序与请求锁的顺序一致,而非公平锁则不保证。

总结

ReentrantLock 和 AQS 是 Java 并发编程的基石。理解它们的原理至关重要,它们为构建高效、可靠的并发程序提供了强大的基础。掌握这些知识,你将成为 Java 并发编程领域的弄潮儿,挥洒自如,让代码并发飞扬!