AQS实现原理?公平锁和非公平锁怎么做到的?
时间: 2024-05-26 19:12:24 浏览: 121
AQS(AbstractQueuedSynchronizer)是Java并发包中的一个抽象类,其主要作用是提供了一种实现同步器的框架,具体的同步器可以通过继承AQS来实现。AQS使用一个FIFO双向队列进行线程的排队等待,实现了一个线程安全的锁的机制。
公平锁和非公平锁的实现方式不同。在公平锁中,等待锁的线程按照先来先服务的原则排队,当锁被释放时,队列中的第一个等待线程会获得锁。而在非公平锁中,等待锁的线程会直接尝试获取锁,如果锁没有被占用,则可以直接获取到锁,否则就会进入等待队列。
为了实现公平锁,AQS中使用了一个FIFO队列来存放等待锁的线程,并且确保锁的获取顺序与线程等待队列中的顺序一致。而在非公平锁中,线程直接尝试获取锁,不需要进入等待队列,所以不需要考虑队列的顺序。
相关问题
详细介绍下AQS 原理?AQS 组件有哪些?
AQS(AbstractQueuedSynchronizer)是 Java 并发包中一个重要的同步组件,它通过内部维护一个 FIFO 队列来实现同步协作,是很多同步组件的基础,例如 ReentrantLock、CountDownLatch、Semaphore 等。
AQS 内部基于一个 int 类型的变量 state 来表示同步状态,当 state 为 0 时表示未锁定状态,当 state 大于 0 时表示已锁定状态,小于 0 时表示 state 的绝对值是等待获取同步状态的线程个数。AQS 的操作主要包括独占和共享两种模式,独占模式下只有一个线程能够获取同步状态,共享模式下可以有多个线程同时获取同步状态。
AQS 的核心是一个双向链表,其中每个节点表示一个等待线程,通过 CAS 操作来实现节点的加入和移除。在独占模式下,等待线程会被加入到队列的尾部,当前获取同步状态的线程是队列头部的节点,当当前线程释放同步状态后,会唤醒队列中的下一个节点。在共享模式下,等待线程也会被加入到队列的尾部,但是当前获取同步状态的线程可能是队列中的任意一个节点,当当前线程释放同步状态后,会唤醒队列中的所有节点。
AQS 组件包括以下几种:
1. ReentrantLock:可重入锁,支持公平和非公平两种模式。
2. ReentrantReadWriteLock:读写锁,支持读写分离。
3. Semaphore:信号量,用于控制资源的并发访问量。
4. CountDownLatch:倒计时门闩,用于等待其他线程完成一定的操作后再执行。
5. CyclicBarrier:循环屏障,用于等待一组线程达到某个状态后再执行。
6. Condition:条件变量,用于在某个条件下等待或唤醒线程。
以上就是 AQS 的基本原理和组件介绍。
阅读全文