java面试系列-手撕AQS

28 阅读2分钟

AbstractQueuedSynchronizer (抽象队列同步器,以下简称 AQS)

  1. 状态(State) :AQS包含一个原子更新的状态值(state),该状态值可以被子类定义和操作。子类通过修改这个状态值来管理自定义的同步策略。

  2. 队列(Queue) :AQS内部维护了一个FIFO的等待队列,用于存储因为同步资源而被阻塞的线程。这些线程以节点(Node)的形式加入到队列中。

  3. 获取与释放资源

    • acquire() 方法:当一个线程需要获取某个共享资源时,它会调用acquire()方法。在这个过程中,线程会根据共享资源的状态(state)决定是否能够立即获取资源。如果不能获取,线程会被加入到等待队列中,进入阻塞状态。
    • release() 方法:当线程使用完资源需要释放时,它会调用release()方法来释放资源,并且可能唤醒等待队列中的某些线程来竞争获取资源。
  4. 同步状态的操作:AQS提供了一系列底层方法,允许子类安全地修改状态值和操作等待队列,以实现自定义的同步策略。其中包括getState()setState()enqueue()dequeue()等方法。

  5. Condition 条件队列:除了基本的同步机制外,AQS还支持Condition对象。Condition对象可以让线程在特定条件下等待或唤醒,用于实现更复杂的线程通信机制。

从本质上来说,AQS提供了两种锁机制,分别是排它锁和共享锁。

排它锁就是存在多线程竞争同一共享资源时,同一时刻只允许一个线程访问该共享资源,也就是多个线程中只能有一个线程获得锁资源,比如Lock中的ReentrantLock重入锁实现就是用到了AQS中的排它锁功能。

共享锁也称为读锁,就是在同一时刻允许多个线程同时获得锁资源,比如CountDownLatch和Semaphore都是用到了AQS中的共享锁功能。

常见的有:ReentrantLock、CountDownLatch、Semaphore等