JAVA面试题分享六:谈谈你对 AQS 的理解?

一、什么是AQS

AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的ReentrantLock,Semaphore,其他的诸如ReentrantReadWriteLock,SynchronousQueue,FutureTask等等皆是基于AQS的。当然,我们自己也能利用AQS非常轻松容易地构造出符合我们自己需求的同步器。


二、AQS 的核心思想

AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。 CLH(Craig,Landin,and Hagersten)队列是一个虚拟的双向队列(虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系)。AQS是将每条请求共享资源的线程封装成一个CLH锁队列的一个结点(Node)来实现锁的分配。 AQS使用一个int成员变量来表示同步状态,通过内置的FIFO队列来完成获取资源线程的排队工作。AQS使用CAS对该同步状态进行原子操作实现对其值的修改。

三、AQS的工作原理

一个线程来获取锁资源的时候,首先会判断state是否等于0,也就是说它是无锁状态。如果是,则把这个state更新成1,表示占用到锁。

而这个过程中,如果存在同时多次做这样的一个操作,就会导致线程安全性问题。因此AQS采用了CAS机制,去保证state互斥变量更新的一个原子性。未获得到锁的线程通过Unsafe类中的park方法去进行阻塞,把阻塞的线程按照先进先出的原则,去加入到双向链表的一个结构中。

当获得锁资源的线程释放锁之后,会从这样一个双向链表的头部去唤醒下一个等待的线程,再去竞争锁。

四、总结 

AQS,全称为AbstractQueuedSynchronizer,是Java并发编程中的一个重要组件。它是一个用于构建同步器的框架,提供了一套基于状态、队列和锁的机制,用于实现线程间的同步和协调。下面我将从几个方面谈谈对AQS的理解:

  1. AQS的核心思想:AQS的核心思想是使用一个int类型的状态变量来表示同步状态,通过CAS(Compare-And-Swap)操作来保证状态变量的原子性更新。同时,AQS使用一个FIFO队列来管理阻塞的线程,当同步状态满足时,唤醒队列中的线程来竞争锁。
  2. AQS提供的两种锁机制:AQS提供了排他锁和共享锁两种锁机制。排他锁同一时间只允许一个线程访问共享资源,如ReentrantLock;共享锁则允许多个线程同时访问共享资源,如Semaphore和CountDownLatch。这两种锁机制都是通过状态变量和队列的管理来实现的。
  3. AQS的工作流程:当线程尝试获取锁时,首先会检查同步状态是否满足,如果满足则直接获取锁,否则会将当前线程加入等待队列并阻塞。当同步状态满足或队列中的线程被唤醒时,线程会尝试获取锁,成功则执行同步代码,否则继续阻塞。同步代码执行完毕后,会释放锁并唤醒等待队列中的下一个线程。
  4. AQS的应用:AQS作为Java并发包(java.util.concurrent)的底层实现,被广泛应用于各种同步器的实现,如ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch等。这些同步器都是基于AQS实现的,通过组合和加工AQS提供的方法来实现各自的同步需求。

总的来说,AQS提供了一种基于状态和队列的同步机制,通过原子性的状态变量和FIFO队列来管理线程的同步和协调。它是Java并发编程中的重要组件,为各种同步器的实现提供了统一的框架和支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之乎者也·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值