AQS(抽象队列同步器)

什么是AQS?

        AQS(AbstractQueuedSynchronizer)是Java中用于实现锁和同步器的基础框架。它是一个抽象类,提供了一种灵活且强大的方式来实现各种同步器,如ReentrantLock、Semaphore、CountDownLatch等

AQS实现原理?

1、资源共享:AQS 中定义了一个整型的 state 变量来表示同步状态,该状态可以被多个线程共享,根据该状态的不同值来表示不同的状态(比如锁被占用或者可用)。

  • 等于0:表示当前同步状态为空闲状态,即没有线程占用资源
  • 大于0:通常表示当前同步状态被一个线程所占用,且在信号量的应用中也可以表示可用资源数量
  • 小于0:一般表示当前同步状态已被某个线程占用,数值表示等待获取资源的线程数量

2、模板方法:AQS 提供了 acquire() 和 release() 两个模板方法,具体的同步器只需实现这两个方法的逻辑即可。其中 acquire() 方法用于获取资源,如果获取不到则会将当前线程加入等待队列;release() 方法用于释放资源,并唤醒等待队列中的其他线程。

3、等待队列:AQS 使用一个双向链表来维护等待线程的队列,队列中的线程按照先进先出的顺序来获取资源。当一个线程无法获取资源时,会被加入到等待队列中并进入等待状态。

4、CAS 操作:AQS 使用 CAS(Compare And Swap)操作来对状态进行原子性地修改,保证多线程并发操作时的数据一致性。

5、子类实现:具体的同步器(如 ReentrantLock、Semaphore 等)需要继承 AQS,并根据自身需求实现 acquire() 和 release() 方法,来实现自定义的同步逻辑。

AQS的辅助类?

Condition

        Condition(条件)是Java中用于线程之间通信的一种机制,常用于对线程的等待和唤醒操作。Condition通常与Lock一起使用,是Lock接口的一部分,用于替代传统的Object的wait()和notify()/notifyAll()方法。在使用Condition时,首先需要获得一个Lock对象,然后通过Lock对象的newCondition()方法创建一个Condition对象。线程可以通过Condition的await()方法进入等待状态,当其他线程调用Condition的signal()或者signalAll()方法时,被等待的线程会被唤醒。使用Condition可以更加精细地控制线程的等待和唤醒,而不像使用Object的wait()和notify()/notifyAll()方法那样具有局限性。

CountDownLatch(减少计数)

 CountDownLatch 是 Java 中的一个同步工具类,用于实现多个线程之间的同步,通过减少计数的方式实现线程之间的等待和通知。

  • CountDownLatch 内部维护一个计数器,通过 countDown() 方法递减计数,通过 await() 方法阻塞调用线程,直到计数器为 0。
  • 在初始化 CountDownLatch 时需要指定计数器的初始值,每次调用 countDown() 方法都会使计数器减 1。
  • 当计数器减至 0 时,所有在 await() 方法上阻塞的线程都会被唤醒,可以继续执行后续操作。


举例:风火雷电四大法王都能封印魔兽,但是随着一个个法王的离开,每次调用countDown()方法,直至没有一个法王存在,魔兽就会苏醒。

CyclicBarrier(循环栅栏)

        CyclicBarrier(循环栅栏)是Java中的一个同步辅助工具,用于在多个线程之间实现同步。它允许一组线程全部达到一个同步点后再继续执行。当所有线程达到同步点时,CyclicBarrier会释放它们并重置,以便可以被重复使用。
        CyclicBarrier是通过指定一个计数值来初始化,当调用await()方法时,线程会等待直到所有参与者都调用了该方法,此时所有线程会被释放并继续执行。CyclicBarrier的一个常见应用场景是将问题分解成多个子任务并行处理,在每个子任务完成后使用CyclicBarrier来等待所有子任务完成后才继续执行其他操作。

举例:召集七颗龙珠即可召唤神龙,每当获取一颗龙珠,会调用await()方法进行等待,一直集齐七颗,才能召唤神龙。

Semaphore(信号灯)

        Semaphore(信号量)是一个用于控制对共享资源的访问的同步工具。它通常用于限制同时访问某个共享资源的线程数量,或者进行线程之间的同步。在Java中,Semaphore提供了一种计数信号量,可以用来控制同时访问某个资源的线程数量,也可以用来实现生产者-消费者模式。
        Semaphore内部维护着一个计数器,初始化时指定初始的许可数量,线程可以通过acquire()方法获取许可(如果计数器大于0则获取成功,计数器减1),通过release()方法释放许可(计数器加1),当计数器为0时,acquire()方法会阻塞线程,直到有其他线程释放许可。

举例:六辆汽车三个停车位,通过acquire()方法占用停车位,通过release()方法离开停车位,但是只能同时停三辆车。

ps:以下是我整理的java面试资料,感兴趣的可以看看。最后,创作不易,觉得写得不错的可以点点关注!

链接:https://www.yuque.com/u39298356/uu4hxh?# 《Java面试宝典》 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值