aqs原理

AQS(AbstractQueuedSynchronizer)是Java并发包中的一个核心基础类,用于构建锁和同步器。它的主要原理是通过一个整型的状态变量(state)来表示同步状态,并使用一个FIFO(先进先出)的等待队列来管理获取锁失败的线程。

以下是AQS的几个关键点:

  1. 状态变量(state)
  • AQS使用一个volatile的整型变量state来表示同步状态。state的默认值为0,表示资源可用;当线程获取锁成功时,state加1;当线程释放锁时,state减1。这种机制确保了加锁和释放锁的原子性。
  1. 等待队列(等待队列)
  • AQS内部维护一个FIFO的双向队列,用于存放那些尝试获取锁但失败的线程。队列中的每个节点(Node)包含线程的信息以及等待状态。当线程获取锁失败时,它会被封装成一个节点并加入到队列的尾部,同时该线程会被阻塞。
  1. 锁的获取和释放
  • 当线程尝试获取锁时,它会检查state的值。如果state为0,表示锁可用,线程会通过CAS(Compare-and-Swap)操作将state加1,从而成功获取锁。如果state不为0,表示锁已被占用,线程会被加入到等待队列中。

  • 当线程释放锁时,它会执行state减1的操作,并通过CAS操作确保只有持有锁的线程才能释放锁。释放锁后,AQS会从等待队列的头部唤醒一个线程,使其尝试获取锁。

  1. 公平性和非公平性
  • AQS支持公平锁和非公平锁。在公平锁中,锁的释放会按照等待队列的顺序唤醒线程;在非公平锁中,新来的线程有可能在等待队列中的线程之前获取到锁。
  1. 扩展性
  • AQS是许多Java并发工具类的基础,如ReentrantLockReentrantReadWriteLockSemaphore等。这些类通过继承AQS并重写相关方法来实现自己的同步逻辑。

总结起来,AQS通过一个状态变量和等待队列来实现线程的同步和锁的管理,确保在多线程环境下资源的互斥访问。这种设计不仅简单高效,而且具有良好的扩展性,使得开发者可以基于AQS构建出各种复杂的同步器。

Top