【java】抽象同步队列AQS

3 篇文章 0 订阅

1、什么是抽象同步队列?

	抽象同步队列AQS(AbstractQueueSynchronized)是实现同步器的基础组件,并发包(J.U.C)包中
锁的底层就是使用AQS实现的。

2、AQS核心思想

	AQS核心思想是,如果被请求的共享资源空闲,则将当前线程设置为有效的工作线程,并且将共享资源
设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,
这个机制就是用CLH队列锁实现的AQS,即将暂时获取不到锁的线程加入到队列中,等待被唤醒。

3、CLH队列

	CLH(Craig,Landin,and Hagersten)队列是一个虚拟的双向队列(即不存在队列实例,仅存在节点
之间的关联关系)。AQS是将每条请求共享资源的线程封装成一个CLH锁队列的一个节点(node)来实现锁
的分配。

4、AQS结构

4.1、
	AQS是一个FIFO的CLH双向队列,其内部通过节点head和tail记录队首和队尾元素,队列元素类型为Node。

4.2、Node结构
  1. Node中的thread变量用来存放进入AQS队列里面的线程。
  2. SHARED用来标记该线程是获取共享资源时被阻塞挂起后放入AQS队列的。
  3. EXCLUSIVE用来标记该线程是获取独占资源时被挂起后放入AQS队列的。
  4. waitStatus记录当前线程等待状态。
    a. CNCELLED:线程被取消了。
    b. SIGNAL:线程需被唤醒。
    c. CONDITION:线程在条件队列里面等待。
    d. PROPAGATE:释放共享资源时需要通知其他节点。
  5. pre记录当前节点的前驱节点,next记录当前节点的后继节点。

4.3、AQS中维持一个单一的状态信息state,可以通过getState()、setState()和compareAndSetState()修改其值。
  1. 对于ReentrantLock,state表示当前线程获取锁的可重入次数。
  2. 对于ReentrantReadWriteLock,state的高16位表示读状态,也就是获取该读锁的次数;低16位表示获取到写锁的线程的可重入次数。
  3. 对于Semaphone,state表示当前可用信号的个数。
  4. 对于CountDownLatch,state用来表示计数器当前的值。

4.4、内部类ConditionObject
	AQS有个内部类ConditionObject,用来结合锁实现线程同步。ConditionObject可以直接访问
AQS对象内部的变量,比如state状态值和AQS队列。
	ConditionObject是条件变量,每个条件变量对应一个条件队列(单向链表队列),其用来存放
调用条件变量的await方法后被阻塞的线程。

5、同步器的设计是基于模板方法模式

	AQS在设计时使用了模板方法的设计模式,即:父类中包含抽象方法,和一些模板方法(已经规定好的步骤),抽象方法提供给子类实现,在模板方法中调用一些抽象方法用于功能的实现。
	所以在实现AQS时就应覆盖它一些抽象方法: tryAcquire(独占式获取锁)、tryRelease(独占式释放锁)、tryAcquireShared(共享式获取锁)、tryReleaseShared(共享式释放锁)、isHeldExclusively(同步器是否处于独占状态)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AQS(AbstractQueuedSynchronizer)是Java并发编程中的一个重要类,它可以理解为抽象队列同步器。AQS提供了一种基于FIFO队列同步机制,用于实现各种同步器,如ReentrantLock、CountDownLatch、Semaphore等。 AQS的核心思想是使用一个volatile的int类型变量state来表示同步状态,通过CAS(Compare and Swap)操作来实现对state的原子更新。AQS内部维护了一个双向链表,用于保存等待获取同步状态的线程。 AQS的具体实现包括以下几个方面: 1. 内部属性:AQS内部有两个重要的属性,一个是head,表示队列的头节点;另一个是tail,表示队列的尾节点。 2. 入队操作:AQS的入队操作是通过enq方法实现的。在入队操作中,首先判断队列是否为空,如果为空,则需要初始化队列;否则,将新节点添加到队列的尾部,并更新tail指针。 3. CAS操作:AQS的CAS操作是通过compareAndSetHead和compareAndSetTail方法实现的。这些方法使用CAS操作来更新head和tail指针,保证操作的原子性。 4. 出队操作:AQS的出队操作是通过deq方法实现的。在出队操作中,首先判断队列是否为空,如果为空,则返回null;否则,将头节点出队,并更新head指针。 5. 同步状态的获取和释放:AQS提供了acquire和release方法来获取和释放同步状态。acquire方法用于获取同步状态,如果获取失败,则会将当前线程加入到等待队列中;release方法用于释放同步状态,并唤醒等待队列中的线程。 通过继承AQS类,可以实现自定义的同步器。具体的实现方式是重写AQS的几个关键方法,如tryAcquire、tryRelease等,来实现对同步状态的获取和释放。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值