知识点: Java公平锁与非公平锁 原理讲解ReentrantLock 锁的饥饿效应及解决办法

本文介绍了Java并发编程中的公平锁和非公平锁,阐述了AQS(AbstractQueuedSynchronizer)的工作原理,并讨论了ReentrantLock在公平性和性能之间的权衡。此外,还提出了解决非公平锁饥饿效应的方法,即设置超时和自旋逻辑。
摘要由CSDN通过智能技术生成


本文知识:

公平锁与非公平锁理论

AQS的理论与原理讲解

公平锁与非公平锁原理讲解

ReentrantLock的使用

非公平锁饥饿效应解决方法

在上篇中分析了Java并发编程中悲观锁与乐观锁的实现算法,并分析了原子类中使用CAS算法实现乐观锁以及ABA、自旋等问题。

延续上篇继续导论Java ReentrantLock锁,如果实现公平锁与非公平锁。

前言

公平锁:多个线程申请锁时是相对公平的,在申请锁时如果有其它线程已经占用了锁,则进行排队等待处理。

非公平锁:多个线程申请锁时相对不公平,与公平锁相同,都会存在排队的情况,但对于一个新线程需要获取锁时不是先排队等待,而是先尝试获取锁,不成功时再进入队列排队等待。

AQS

在分析公平锁与非公平锁之前,先来讲讲AQS这个家伙。

AQS全称AbstractQueuedSynchronizer,它实现了锁的等待队列、锁的获取与释放;它是一个抽象的实现。

image-20210610213207759

AQS使用链接实现一个FIFO队列,使用state表示锁的状态,当state大于0时表示当前已经有线程占用锁了,在Thread1已经占用锁后再重复调用加锁操作时state会+1,这样就实现了重入锁,每次释放锁时state会-1,为0时完全释放锁,队列中等待的第一个线程可以开始获取锁。

AQS更多的内容后面再单独写一篇详细的文章进行分析,今天转入正题公平锁与非公平锁。

公平锁

线程在获取锁时以公平的形式进行,没有线程占用锁时可以直接获取锁成功,已经有线程占用锁或者已经有人在排队时将进入队列排队等待。公平锁不会出现饥饿效应,所有的线程都有可以获取到锁,但对CPU唤醒线程的开销较大,线程越多开销越大。下面用一个售票排队的例子来解释公平锁:

image-20210611095622492

售票窗里的售票员负责卖票,相当于AQS中的state变量,一个购票人一次可以买n张票,出队了还需要买票就需要重复排队,新购票人来买票时看当前售票窗有没有人正在买票,没有就可以直接买票,有就需要排队,排队就相当于AQS中的FIFO队列。就样的过程就是公平锁实现的思想,票是资源由售票员进行管理与售卖,买票需要有秩序,不能插队,让所有买票的人都是公平的,谁先来谁先买。

非公平锁

线程获取锁时以不公平的方式进行,公平锁获取锁的方式是进入队列排队取锁,而非公平锁与公平锁在的区别只要就在排队上,非公平锁可以在队列的第一位的位置进行一次插队,插队成功就可以先获取锁,没有插队成功就需要像公平锁一样进行排队等待获取锁。非公平锁可能什么出现饥饿效应,队列中等待的线程与新来获取锁的线程在锁获取上是不公平的,有插队这一行为,正是因为有这一行为就有可能导致队列中等待的线程等待时间过长而出现

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值