AQS面试题

更多面试资料请添加wx:suns45

———Java的AQS———

1、AQS的理解

  1. AQS是一个锁框架,提供了扩展地方

  2. 当多个线程抢锁时,获取不到锁的线程,AQS会自动管理

  3. AQS是同步队列+条件队列

  4. AQS分为4个时机,获取锁,释放锁,条件队列的阻塞、条件队列的唤醒。

2、 多个线程通过锁请求共享资源,获取不到锁的线程怎么办?

  1. 尝试获得锁,获得锁了直接返回,获取不到锁的走到 2;

  2. 用 Node 封装当前线程,追加到同步队列的队尾,追加到队尾时,又有两步,如 3 和 4;

  3. 自旋 + CAS 保证前一个节点的状态置为 signal;

  4. 阻塞自己,使当前线程进入等待状态。

3、排它锁和共享锁

  1. 排它锁只会唤醒头节点,

  2. 共享锁还会唤醒头节点和后续节点。

4、排它锁和共享锁的区别

  1. 排它锁的意思是同一时刻,只能有一个线程可以获得锁

  2. 共享锁可以允许多个线程获得同一个锁

5、同步队列

结构

  1. 双向链表,头是head,尾是tail

  2. 节点是Node,Node里面是prev和next属性

作用

阻塞获取不到锁的线程

大致过程

1.多个线程获取锁时,只有一个线程能获取锁,封装成node加入到同步队列当中

2.当有锁释放时,同步队列释放头节点。

6、进出同步队列的时机

  1. 进队列

1.多个线程获取锁时,获取不到锁的线程进入队列

2.唤醒条件队列,从条件队列移入同步队列

  1. 出队列

1.锁释放。

2.线程进入条件队列。

7、条件队列的作用

  1. 对同步队列的场景功能补充,比如队列满时,put线程,队列空时,take线程。

8、条件队列元素入队和出队的时机和过程

  1. 入队:执行await方法时,线程会释放锁,进入条件队列

  2. 出队:有线程signal/signalAll时。

9、描述一下条件队列中的节点转移到同步队列中去的时机和过程?

时机

  1. 当有线程执行 signal、signalAll 方法时,从条件队列的头节点开始,转移到同步队列中去

过程

  1. 找到条件队列的头节点将next设置为null,移除条件队列

  2. 将该节点追加到同步队列队尾

  3. 状态从Condition设置为0

  4. 节点的前一个节点设置为SIGNAL阻塞自己。

10、线程入条件队列时,为什么需要释放持有的锁?

  1. 原因很简单,如果当前线程不释放锁,一旦跑去条件队里中阻塞了,后续所有的线程都无法获得锁,正确的场景应该是:当前线程释放锁,到条件队列中去阻塞后,其他线程仍然可以获得当前锁。

11、我要自定义锁,大概的实现思路是什么样子的?

  1. A类,在A类里面写一个内部B类继承AQS,实现tryAcquire和tryRelease两个方法,通过state是0判断可以获取锁,通过state递减为0可以判断释放锁

  2. 在A类中对外提供,lock和unlock方法

12、描述ReentrantLock两大特性:可重入性和公平性?底层分别如何实现的?

  1. 可重入性:对同一个资源重复加锁state会加1

  2. 公平性:按照线程入队列的顺序释放锁

  3. 底层:通过hasQueuedPredecessors,会判断当前线程节点是否是头结点的下一个节点。

13、如果一个线程需要等待一组线程全部执行完之后再继续执行,有什么好的办法么?是如何实现的?

  1. CountDownLatch 就提供了这样的机制,比如一组线程有 5 个,只需要在初始化

  2. CountDownLatch 时,给同步器的 state 赋值为 5,主线程执行 CountDownLatch.await ,子线程都执行 CountDownLatch.countDown 即可。

14、Atomic 原子操作类可以保证线程安全,如果操作的对象是自定义的类的话,要如何做呢?

Java 为这种情况提供了一个 API:AtomicReference,AtomicReference 类可操作的对象是个泛型,所以支持自定义类。

15、CountDownLatch和CyclicBarrier区别

CountDownLatch
  • CountDownLatch:有两个api,在创建的时候指定 数量,await,countDown

  • 适用场景

    1. 当商品进行退货的时候,不使用Countdownlatch,需要遍历退货,返回给前端结果
    1. 使用Countdownlatch,可以并发执行退货,返回给前端结果
  • CountDownLatch是什么?

    • 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行
CyclicBarrier

https://makedown-psl.oss-cn-beijing.aliyuncs.com/psl/1685631048479-c3a00e5e-02ab-41c2-a170-66ba228347cf.png

  • CyclicBarrier:

    • 只有1个await的api 在创建的时候指定 数量,等待指定数量的线程执行完成之后才可以去执行后面的逻辑。
  • 是什么?

    • N个线程,他们之间任何一个没有完成,所有的线程都必须等待

    • 每个线程代表一个跑步运动员,当运动员都准备好后,才一起出发,只要有一个人没有准备好,大家都等待.

CountDownLatch和CyclicBarrier区别
  • 重用区别

    • CyclicBarrier 可重用

    • CountDownLatch 不可重用,计数值为 0 该 CountDownLatch 就不可再用了

  • 概念区别

    • CountDownLatch 是计数器, 线程完成一个就记一个, 就像 报数一样, 只不过是递减的.

    • CyclicBarrier更像一个水闸, 线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值