【747、说一下 AQS?看过锁的源码吗?说下 ReentrantLock 的实现】

92 阅读2分钟

AQS(AbstractQueuedSynchronizer)是Java中用于实现同步器的抽象类。它提供了一种基于FIFO等待队列的机制,用于构建各种类型的同步器,例如锁(如ReentrantLock)和信号量(如Semaphore)等。AQS内部维护了一个同步状态(state),并且支持线程的排队和阻塞、唤醒等操作,以实现线程的同步与互斥。

ReentrantLock是Java中一种可重入的互斥锁,它的实现就是基于AQS。ReentrantLock实现了Lock接口,并提供了更灵活和强大的锁定机制,相比于synchronized关键字,ReentrantLock具有更多的特性和灵活性。在ReentrantLock的实现中,它通过AQS的帮助来管理线程的排队和同步状态的控制。

ReentrantLock的实现基于AQS的模板方法模式,它主要涉及以下几个关键方法:

  • lock():尝试获取锁,如果锁不可用则阻塞等待。
  • unlock():释放锁。
  • tryAcquire():尝试获取锁,成功返回true,失败返回false。
  • tryRelease():尝试释放锁,成功返回true,失败返回false。

ReentrantLock内部维护了一个同步状态变量,通过AQS的模板方法来控制该变量的获取和释放。每次线程调用lock()方法时,它会先尝试通过调用tryAcquire()来获取锁,如果tryAcquire()返回true,表示获取成功,线程可以继续执行后续代码;如果tryAcquire()返回false,表示锁已被其他线程占用,则当前线程会进入等待队列并被阻塞。当一个线程调用unlock()方法释放锁时,它会调用tryRelease()方法来释放锁资源,并唤醒等待队列中的下一个线程。

ReentrantLock的实现利用AQS提供的底层机制,实现了线程的同步和互斥。它支持可重入特性,允许同一个线程多次获取同一把锁而不会产生死锁。同时,ReentrantLock还提供了公平锁和非公平锁两种模式,以及可中断的获取锁操作和超时获取锁操作等高级特性,使得它比synchronized更加灵活和可控。