AQS的非公平锁与同步队列的FIFO冲突吗?

21 篇文章 0 订阅

公平锁与非公平锁的含义都很明白,公平锁必须排队获取锁,锁的获取顺序完全根据排队顺序而来,而非公平就是谁抢到是谁的
我们都知道AQS中的锁获取,如果首次获取失败会进入到内部的同步队列中阻塞等待,只有前面的节点唤醒当前节点才能去尝试获取锁

从我之前的博客内容可知,锁获取的核心,实际上是在try方法中定义的,在节点从阻塞中醒来时,都会用try方法来获取锁,而公平与否在try方法中体现,即在公平锁中,try获取的前提时需要没有存在前驱节点的,而非公平锁就没有这个限制

但是!同步队列不是FIFO的吗,它们入队排好顺序并且按照顺序一个一个的醒来,只有醒来的才有机会去获取锁,才能去执行try方法,这不还是公平的吗?

解答

线程在do方法中获取锁时,会先加入同步队列,之后根据情况再陷入阻塞。当阻塞后的节点一段时间后醒来时,这时候来了新的更多的线程来抢锁,这些新线程还没有加入到同步队列中去,也就是在try方法中获取锁。
在公平锁下,这些新线程会发现同步队列中存在节点等待,那么这些新线程将无法获取到锁,乖乖去排队;
而在非公平锁下,这些新线程会跟排队苏醒的线程进行锁争抢,失败的去同步队列中排队。
因此这里的公平与否,针对的其实是苏醒线程与还未加入同步队列的线程
而对于已经在同步队列中阻塞的线程而言,它们内部自身其实是公平的,因为它们是按顺序被唤醒的,这是根据AQS节点唤醒机制和同步队列的FIFO特性决定的

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
AQS(AbstractQueuedSynchronizer)是Java并发包中的一个基础框架,用于实现同步器(synchronizer)和(lock)等机制。AQS提供了公平公平两种实现方式。 公平公平是指多个线程按照申请的顺序来获取,即先到先得的原则。当一个线程释放时,等待时间最长的线程将获得的访问权。在公平中,通过一个队列来维护等待获取的线程顺序,每个线程在申请时会先检查队列是否有等待线程,如果有,则进入等待队列并等待自己的机会获取公平公平是指多个线程获取的顺序是不确定的,不保证按照申请的顺序来获取。在公平中,当一个线程释放时,下一个获取的线程可能是刚刚释放的线程本身,也可能是其他正在等待的线程,这样可以减少线程切换的开销。 公平公平在性能上有一定的差异。公平由于需要维护一个有序的等待队列,增加了一些额外的开销,可能导致整体的性能较低。而公平则没有这个开销,可能会导致某些线程长时间等待,出现“饥饿”的情况。 在实际应用中,选择公平是非公平取决于具体的场景和需求。如果对于线程获取的顺序有严格要求,需要保证公平性,可以选择公平。如果对于性能要求较高,允许线程获取的顺序不确定,可以选择公平

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值