00:00
各位同学大家好,接下来我为大家介绍公平锁和非公平所。先从字面意思,那么这个所谓的所的公平和非公平是如何来体现的呢?那么它主要是指Java多线程抢夺同一份资源的时候,为了避免乱续和挤压,那么保证数据的一致性和安全性,都要先持有锁,那么在持有锁各个线程它所获得锁的几率是不一样的。有可能按照公平锁的概念,那么就是假设十个线程来抢夺同一份资源公平,那么大家轮着一点雨露均沾,那么另外一种情况非公品,那就不好意思了,大家都来抢,群雄逐鹿,谁先抢到就是谁的好,这就是公平和非公平最本质上的意义。持有所、抢夺所获得所的概率不同。好,那么同学们,下面我们先来看案例。从lock卖票的DEMO来演示公平和非公平的现象。
01:01
来,同学们,为了节约大家时间,我提前写好一个卖票的案例。这个票有50张,模拟三个售票员卖完,50张票卖完即可,谁卖的无所谓,那么接下来我们大家呢,来看一下啊,由于呢,大家呢,学到了guc的高级部分了啊。那么对于卖票的程序是helloard级别的,我呢就不再赘述,一看大家就应该懂,那么这个呢?封装了一个资源类,里面呢有50张票,有一个re lock,这个我后面会详细深度的讲解,默认已经学会使用,那么我们大家都清楚,所有的look就是这儿,什么都没写。对吧,你也晓得什么都没写,它代表它是什么?非公平锁,那么在这个资源类里面有一个方法,那么就是卖票哪一位。售票员进来了,或者说某一个县城进来了,Lock,按lock,那么是不是我们的进来,出去解锁示范持有所的进来,就干这么一件事,如果票数还没有卖完,就继续卖好,那么接下来main方法是一切程序的入口,那么线程就是ABC3个。
02:09
县城三个售票员操作同一份资源内六出来的这个实际对象ticket,那么下面对县城进行什么操作?卖票的操作好,那么同学们第一个先来演示非公平,我这儿没有写,就代表默认的是非公平锁,我们跑一下来看一下。什么情况?哎,然后呢,50张票,当然现场之间的争抢会切换,有没有发现它持有所和获得获得所的概率根本没有ABC3个同时出现。别忘了,我这儿是不是三个售票员只有什么A跟C,那么请问50张票,A和C2个售票员分光了,B是不是根本没抢到?那么对B是不是有点不公平?好,我们再执行一次。来,同学们这次就更过分,是不是全是A1个人就包圆了?OK,所以说默认这个就是什么非公平锁,那么想得锁,获得锁的几率不公平,有可能。
03:09
就是同一个线程全部拿走,那么接下来我们想,A,你吃相别那么难看,能不能公平一点?我们希望雨露均沾,那么如果对远成的洛克这个构造方法了解的话,我们大家可以传一个TRY关键字和布尔值进去,那么这时候大家请看fire,这不公平,那么大家请看非公平的时候。全是A强大,那么此时如果我们是设置为公平锁呢?那么大家可以看一下。他抢夺资源,获得线程资源,一开始啊还是AA,但是慢慢的有没有发现ABCAABCA吃线是不是慢慢的被摊薄了,慢慢的大家都平均了,吃线也就不这么难看了,ABC,好,那么同学们我们再跑一次看一下,刚开始啊可能是某一个线程啊,一家独有,但是呢,越来越随着时间的推移和线程的执行情况,所的分配机制啊,发生了根本性的变化,基本上能做到ABCACA3个大家都能匀到一点,这个就是公平锁好,那么所以说。
04:15
我们现在可以得出什么叫公平锁,什么叫非公平锁来,各位同学。所谓公平锁,最经典的也最简单的理解就是我们排队打饭先到先得,对吧?是指多个县城按照申请所的顺序来获取所,类似于排队买票,排队打饭,先来的人先买,后来人对位排着,这是公平的。那么大家可以看得出,如果主lock设置为true,表示公平所先到先得。第二种呢,非公平锁是指多个线程获取锁的顺序,大家请看,并不是按照申请锁的顺序,我们也晓得,如果我们这儿又恢复成非公平锁的话,有可能同一时间就只有一个线程,就把这50张票全部搞定,那么大家请看B,只有A和CB也过来申请了,但是不好意思啊,A跟C抢夺的更狠,他们先获得了,那么B一直没有获得,那么这个时候就会导致什么?
05:12
某一个线程一直得不到,所我们对这种现象就叫做什么线程获取锁的饥饿状态。那么大家可以看得出。这个B本次根本没有抢到,是不是被活活饿死了,所以说这个时候就会出现他呢。获取所的顺序并不是按照申请的顺序,有可能ABC3个售票员都去申请。不好意思啊。我们只给A跟CB,你没有获得,所以说呢,他呢。在高并发的环境下面呢,就容易造成优先级的翻转或者所饥饿,不是你申请了就可以获得,也不是说你后申请的线程就会比先申请的线程优先获得,所那么在这如果是false或者是空的默认都是什么非公平锁,OK,好,那么各位同学我们接下来就要看看。
06:01
为什么会有公平锁和非公平锁的设计?存在一定有它的道理,而且为什么默认是非公平锁,我们大家都知道,一般我们在使用的时候,这个里面是不加触这个关键字的,对吧,那么为什么呢?为什么默认是非公平锁呢?这也是一些面试题和考官他经常问的。来。各位同学漏。首先啊。恢复挂起的线程到真正所的获取是有时间差,这个呢在我们程序员看来是很少的,但是从CPU的角度而言,这个时间差存在的很明显,一句话非公平所能,更充分的利用CU的时间片,尽量减少CPU的什么空闲状态,那比如说我们这个,你只要把50张卖完就行了,我管你公平不公平,那么我们这儿干脆。强者恒强,你C你愿意多卖,你抢到了,我干脆每次都给C,哎,我只要卖完50张票,比方说。A。卖完了七张,剩下的全部给C,我卖完就完了,我不用什么还考虑,因为不好意思,C你买的太多,我得去后面去等着这个B,否则B就会饿死了,没有我们这个时候呢,就避免了是吗?我们的一种切换避免了我们的一种等待,所以说在这块风非公平锁更能充分的利用CPU搞定就行,我也不想去什么云这些获得锁的概率。第二个使用多线程最重要考虑点是线程的什么切换,前面说过了。
07:28
我们现在呢?一个线程或者两个线程就搞定,但是到后面我们对于处的话,看得出ABCABCABC很公平,那么这个时候是不是会出现什么线程切换的开销啊?那么当我们采用非公平锁的时候,一个线程请求锁获取同步状态,然后释放。刚刚释放的线程在此刻再次获得同步组的概率就会变得非常大,哎,那么所以呢,就可以减少线程的是吗?切换的开销,所以说非公平的效率是好过公平的,我没有那么多要去匀下这样的概念,谁先强调就是谁的干完就行,哎,所以说这个时候他们两者是不一样的,性能效率和切换的耗损成本的考虑,那么什么时候用公平,什么时候用非公平,那么看你的业务,比如说像我们卖票假设。
08:13
卖完就行,越快越好,那干脆我们就用非公平锁,只要有人卖就行了,至于说谁卖了,谁没卖,我们不关心,不考虑你切换的成本。那么第二种,那不好意思啊,我这儿呢,对效率对性能的要求不是这么高,我们还是要保证每个点都能卖出去,不能说有些点是卖完了,有些点是关头,所以说我们这儿就要看我们的业务,如果为了更高的吞吐量,性能最优,那么很显然非公平比较合适。因为它节省了这个切换的时间,吞吐量就上来了,否则我们就要用公平锁,那么大家雨露均沾,人人都有范儿,好,那么这个呢,就是我们的公平和非公平,那么接下来我们来看一下。为什么这儿有一个处就是我们的公平锁,这不写就是我们的非公平锁呢?Re enter lock,它底层原理和原码又是什么概念呢?那么这我们先预埋伏我们后面的章节aqs,那么希望大家跟着张阳老师呢,可以学到后面,越到后面越难,那么这个就是我们的抽象的队列同步系简AQS,它是一切GC编成各种所相关的基础,那么来。
09:24
各位同学,我们来可以看一下源码,对于我们的re lock,我们这儿就先不打开了,这个是个类,它实现了lock接口里面有一个AQS抽象的队列同步器,它在这个里面体现了非公平锁和公平锁,我们表面上刚才我们看得出。传了个处,或者是不写。那么这个时候它就根据你的参数来确定公平还是非公平锁,哎,它底层的变化有这么一个think,那么它到底是什么呢?我们呢与埋伏更进一步的源码深度分析,我们进行后续的第13章,好,我们在这儿就给大家公平锁和公平锁,非公平锁就给大家说到这。
我来说两句