【Java并发】什么是AQS?

什么是AQS?

全称是 AbstractQueuedSynchronizer,即抽象队列同步器。它是构建锁或者其他同步组件的基础框架

所谓抽象,其实目的就是把具体的逻辑交给子类去实现,这样就可以实现不同的特性的锁:
例如:AQS常见的实现类
ReentrantLock 阻塞式锁
Semaphore 信号量
CountDownLatch 倒计时锁

AQS是多线程中的队列同步器。是一种锁机制,它是做为一个基础框架使用的,像ReentrantLockSemaphore都是基于AQS实现的.

AQS其实是一个抽象类,它实现了线程挂起的逻辑,实现了线程存储机制,实现了锁的状态逻辑,实现了线程唤醒的逻辑,却只定义了线程抢锁释放锁抽象,这样做的目的是将抢锁和释放锁的逻辑交给子类来实现,这样有助于实现各种不同特性的锁,比如共享锁,独占锁,公平锁非公平锁,可重入等。并且以模板方法模式将上述上锁流程和释放锁流程封装为固定模板方法。

所以AQS就是一个多线程访问共享资源的同步器框架。

AQS与Synchronized的区别

在这里插入图片描述
所以相比较Synchronized,基于AQS基础框架实现的各种特性不同的锁,对于解决多线程下锁的竞争可以提供不同的解决方案。

AQS-基本工作机制

AQS类自身有几个比较重要的属性:

```java
//正在持有锁的线程
private transient Thread exclusiveOwnerThread;
//等待队列的头节点
private transient volatile Node head;
//等待队列的尾节点
private transient volatile Node tail;
//锁标识字段
private volatile int state;

通过锁标识字段state来标志线程是否拥有锁
在这里插入图片描述
AQS-多个线程共同去抢这个资源是如何保证原子性的呢:
通过CAS操作(比较再交换)设置 state 状态,保证操作的原子性
在这里插入图片描述
当线程0和线程4同时去抢锁(修改state的值为1时)采用CAS的操作,使得线程0将state设为1,这时线程4再去修改state时不满足CAS操作的规则,这个时候不会自旋,而是直接加入(FIFO队列)等待队列。
在这里插入图片描述

AQS是公平锁与非公平锁

所谓公平不公平取决于:竞争的线程是队列的还是新的线程
新的线程队列中的线程共同来抢资源,是非公平锁
新的线程到队列中等待,只让队列中的head线程获取锁,是公平锁

公平锁:
在这里插入图片描述
在这里插入图片描述

当线程0释放锁的时候,让head指针指向的线程(线程1)去获取的锁执行自己的业务。
这就是公平锁

非公平锁:

在这里插入图片描述当线程0释放锁的时候,正好又有一个新的线程(线程5)进来了,那么如果线程5拿到了锁,队列中的head指针指向的线程没有拿到锁,
这就是非公平锁
在这里插入图片描述
公平锁和非公平锁各有优缺点,适用于不同的场景。公平锁的优点在于各个线程公平平等,每个线程等待一段时间后,都有执行的机会,而它的缺点相较于于非公平锁整体执行速度更慢,吞吐量更低。同步队列中除第一个线程以外的所有线程都会阻塞,CPU唤醒阻塞线程的开销比非公平锁大。

而非公平锁非公平锁的优点是可以减少唤起线程的开销,整体的吞吐效率高,因为线程有几率不阻塞直接获得锁,CPU不必唤醒所有线程。它的缺点呢也比较明显,即队列中等待的线程可能一直或者长时间获取不到锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值