00:00
各位同学大家好,我们继续通过上一讲,我们已经完成了at的方法,那接下来是最复杂的一个long accumulate,通过前面源代码的分析,我们大家都清楚。二的一大堆if判断,其实质而言,底层干活的是它涉及到新建cell数组,甚至是数组的扩容,以及各种CS的竞争操作,怎么摆放这些数据,分散热点,达到我们的并发的技术,好,那么这个时候我们大家呢,不妨先来看一下。这个方法大致从216行一直到我们的293行,那如果说没有老师的帮助和带领,那么你可能呢,会生吞活剥,从上到下的硬抗,那么这样的话。不是不可以,但是你会发现你做起来呢非常费功夫,那么几乎是事倍但是公半,所以呢,下面请允许我带着大家呢,挨个挨个的来说一下,那么本次我们来看一下。
01:04
这个源码该怎么看呢?首先我们先了解一下前提和基础知识,这个入参,那么前面我们说过啊。对于我们爱的方法,这些都不OK了,以后我们在这儿。假设它是处a.CS某个单元,它竞争失败了,CS啊,这个时候,这个时候大家告诉我是不是从处变成了false,那么所以说它传进来的这个是个force,说明有一些竞争好,所以说long accumulate这三个,我们就先来看看它的入仓分别是什么。首先X啊,那么就是这个一对吧,我们前面强调过这个二的永远就是加这个一。好,那接下来它呢,FN呢,默认传递的是什么?是个那刚好不用管它,所以说里面的FN我们就把它当做是,那那么下面这个是个一也不用管它,重要的就是它,它现在是什么,代表是否产生了竞争,竞争标识如果是force则代表有竞争产生,OK,所以说。
02:09
当前的线程CS竞争失败了才会是false,因为我们这儿看到了,假设这CS成功了过,但是如果这个CS挂了是false,那么有可能会传一个false进去,OK,那么false前面取反了,那么我们呢,才能是变成true true的话呢,咱们再进来,好,那么下面。搁到这儿,我们想挨个挨个逐个往下看,这是第一组第二个。需要有些前置知识啊,那么64类当中的话,有一些变量或者方法的定义来,同学们,那么有base啊,这个这个这个这个这个我们待会挨个挨个的过,那么为了避免反复的切换。老师呢,已经提前给他抓好了,待会儿我们直接看图好了,那么完活儿以后,我们接下来呢,先来说一下我们在爱的方法,这见到过的这个get approach。
03:02
Get proper,那么它呢,是个什么东西呢?来。首先我们来看看源代码。这个时候它是返回proper value对于当前线程O吗?那底就是当前线程pro。我点大家请看它是按F类,然后呢。这个是现成类里面,它自己内部定义的这么一个通道,那么现成的什么随机pro这么一个值,那就请听好,得到这个呢,有什么用呢?说穿了,Get in,得到一个数字,OK。听好,可以把它理解为就是本次参加工作,这个县城就像新员工入职得到一个工号,得到一个信用卡上的工号,他主要干的是得到我们的一个什么现成的哈希值,来,大家请看。看了源码以后,我给大家呢进行详细的分析和解读。第一个。
04:00
因为为什么需要这个哈希值呢?存储线程的这个pro也相当于这个哈希值,理由是这样的,你没有哈希值,你怎么知道我要进到哪个槽位里面,对吧,和我们的哈希迈是一脉相承的,所以说呢,搁到这儿他是这么干的。默认H2是等于零,如果我用这个方法返回零,说明随机数没有被初始化,就说你等于零的话是不可以的,零的话你没有办法进行哈希槽位的计算,所以呢,我这儿大家请看啊,我们源代码。搁到这儿,如果你等于零,它会告诉你什么强制给我初始化,也就是说你这个参加。工作的这个线程必须要有一个哈希值,每一个新员工都需要有一个工号,那么来通过这个得到这个哈希值,然后呢,告诉你was uncon又恢复成错,OK,那么这个呢,就说明什么,我得到一个新的哈希值。重新参与竞争了,那么前面可能抢不到的那个哈希值作废,我有一个新的了,OK,好,那么这块相当于说特殊极端情况啊,等于零的时候。
05:03
那么回到这儿,那么相当于说这个呢是强制初始化,刚才我们也看到了,那么重新获得这个哈希值,好比一个全新的线程一样,所以设置了这个呢,等于初二,那么相当于说was UN contented是没有竞争了吗?错,是的,OK,因为哈希值都变了,之前那个哈希值作废了,那么重新计算了当前线程哈希值号认为此次不算是一次竞争,都还没有被初始化呢,那么所以说肯定还没有存在激烈的。这个竞争,所以说它的状态重新设置为true,好,那么get pro这个呢,我们大家了解一下,都是从线程里面通过Una类得到一个int OK,那么这个呢,就是我们的第一个。知识点请看它是个哈希值,那therea非零的一个好吗?所以说呢,这个呢,先获得它,那接下来。我们就明白了,这个是个项目,新员工入职得工号,新县程得哈希值参与竞争,那接下来我们就要看看这一大段该怎么看呢,注意。
06:03
三段千万不要从头开始看啊,那么就是第一个。它首先是个什么大型的自学,OK,相当于Y能跟上,中间有很多break可以跳出去,好,那接下来这是第一个,那么第二个它总干分三段,哪三段呢?杨哥呢,给他整理了一下啊,上面这个是哈希,挺好在这块。就是我们的开始,下面分成CASE123,那么分别是这个是三,数组已经被初始化,就相当于说已经有数组建好了,第二种情况是没有加锁且没有初始化,那么相当于说我们要新建一个。初始化好exce数组,第三种情况是sales正在进行初始化,那么在竞争激烈的前提下,这块还没初始化好呢,但是多线程嘛,它你你里面正在干着工作的时候,外面一大堆线程也在访问,所以说这个是什么一个兜底的尝试,直接在技术base上进行累加操作,所以说这一大个负循环。
07:08
123。再次强调一遍,千万不要123顺着看,但是我们把它分成三段,这三段分别是什么意思啊?来给大家做一个总干的介绍,上述代码,首先要给当前线程分配好一个哈希值啊,没问题吧,新员工入值啊,有工号新线程进来,来抢夺这些槽位的坑位,进行数据的加载,要给你分配一个哈希值啊,然后进入一个大型的负自旋,这个自旋分为三个分支啊。开始写。已经初始化好,K2没有初始化,这个叫什么?首次新建K3是正在初始化当中,要有一个兜底的,我们还是回去找我们的贝类。世上只有妈妈好,还是回去找贝斯老妈?OK,好,这个就是我们的总干,那么最后我们来看看他的计算,那么分成三坨。
08:00
我们看的时候呢,一定是从二幺,213或者是231的顺序来看,那么我们这次呢,就选择第二第三和第一三段来看,OK,这个是最简单的,首先啊,同学们老爷。大型负循环对吧,那么这个比较复杂,也就是说现在的。呃,高亮显示273号,273行以前我们待会说,那么我们先根据我们之前看到过的,先看这两段,简单的这个就是我们的K2,这个就是我们的K3,他是这么干的。以前还记不记得,如果这个方法失败了,False整体取反是错处,就进来,进来默认的话,四要数组是什么,是不是那是那,那说明什么,根本没见过呢,所以说直接进到这,那么进到这了以后,我们大家请看这个分支什么CL速组已经建好了,不能等于那,那对不起,现在我们刚好等于那,所以说我们现在刚刚初始化,这速组是属于什么首次新建那么。
09:05
未初始化过C素组,尝试占有所并首次初始化我们的CE素组,那么这段代码弟兄们,我们呢,已经见过了,OK,在这儿详细给大家说来。上一讲告诉大家不要理这次啊,我们详细说,那么现在相当于说我们要新建sales数组,先走这个分支啊,请看sales busy,那么什么叫sales busy?大家请看什么int类型是个数字零,说出了就是个通过CS进行自选索。当我们需要。创建cell的时候,这个零就代表是什么?默认没有人占用,这么说能跟上好,那么同学们是啥意思呢?你们大家请看啊,初始化sales或者扩sales需要获取锁,零表示无锁状态,也就是没有人抢占,一表示其他线程已经持有锁,那么一刚刚刚开始啊,我们在这块啊,我们要新建我们的数组。看看它是不是等于零,我是是第一个新建这个数组的人,能跟上,就相当于说我们以前说过这个贝斯啊,不够用了,现在要新建数组对吧,所以说当然等于零了,那么sales,这个sales什么意思呢?也就是我们这个C单元格数组对吧?然后呢,等于as啊,然后并且CS CS busy,也就是说它怎么着,我们来看看当前这个三是不是零,也就是说。
10:26
没有人占用,听懂了吧,天时地利人和好,那么这是个cns操作,那么接下来我们一那么默认。是force,然后串二,我们前面说过干嘛初始化这个数组,前面也介绍过,这干嘛西安单一是不是新建了一个单元初始值设为二的Excel单元格数组。那么前面。我们也给大家演示过对吧,那么相当于说这贝斯不够用了,那么现在新建两个好,那么新建两个以后,那么在这H啊,就是这个哈希值上面的和这个一做了一个。
11:02
微因素啊,那么RS啊,就是这个cel数组,那么就把我们刚才丢进来,这个X是一写进去假设啊,我们现在呢,就是有两个坑位,这是零号坑位,这是一号坑位,我们现在你有了这么一个只是有坑,但是还没有数字呢,对吧,有坑还没有萝卜呢,那么现在。它干了以后就给其中假设啊,这就是一,就把这个一写进去,那么现在我们的这一号看位这个值啊,就是1OK,那么现在C就把这个数组呢引下来,就是我们的RS,那么unit等于完活,相当于说这个unit,那么就是从false到这个成功的实现了速单元值为二的下标为二的一个速组,OK,那么这样我们现在呢,又重新把它弄为零,证明什么我初始化完成,我用完了,我要把它置为零吗?然后这个unit里已经是变成了初二,这个是初二瑞跳出这个大型。循环OK,第一组就获得了结束,那么在这儿同学们我们来有些细节来看一下啊。
12:08
首先sales啊,等于这我这红色的这写着啊,有没有发现有点类似于我们的双端检索机制啊,那么现在如因为你在建的过程当中啊,也有别的线程在干,有可能CPU的时间调度你停了,你被挂起了,所以说我们两次检查,如果你不双端检索,就会再次你有exl速度,上一个线程对应数度中的值将会被篡改,那么所以说从安全有效的角度,我们两次检索,那么进来这是新建一个大小为二的CL速组,搁到这儿是找到当前线程哈希道数中的位置啊,并创建其对应的CL,那么比如说我们这就。随便写啊,一号摊位这个值啊,写进来是一好。所以说如果上面条件都执行成功,就会执行数组初始化和负值操作,这个表示数组的长度为二,说过了,那么这个表示创建一个新的CL元素value X的值默认就是1H和一,类似于我们这些哈希map用到的计算散六桶的算法,那么通常都是这个从哈希map是一个意思这一段那么只要有哈西map的基础都好说,那么这。
13:12
解决完成,相当于一个数组下标为二的三要单元格,三单元格数组搞定,那么下面这是什么都底,世上只有妈妈好意思是这样的。这个呢,初始化新建,你只能会新建一次嘛,对吧,那么接下来如果啊,上面竞争太激烈,你抢不到,那么到最后需要有个兜底的,那么就是它,那它的意思是这样的,多个线程尝试CS修改失败的线程都会走这个分支啊,就是说啊,上面你看有这么多,你看if if if if if l if l等等等等这些各个分支什么意思啊,我们待会聊,但是。如果新建已经新建完了,这个分支应该不走了,那么现在就会走我们的K3,那么深刻体会一下,我我这个总干这是不是个大型的负循环,然后1232是什么首次新建,三是宿组的兜底的,可能正在初始化,还没有二还没有彻底出阳胎呢,那么这个时候一大堆线程涌上来,那么总要有个兜底,对吧,那么所以说它会走到三,所以呢,隔到这儿我们来来尝试多个线程,尝试CS修改失败的线程将会走到这个分支,那么来同学们。
14:19
这儿我们来看一下,那么还是对我们那个贝斯,相当于说对我们这个贝斯OK进行CS操作,V等于base Fn是不是等于钠,前面说过FN永远是等于钠,那么这是就什么处第一个反过来没有一加,所以说CS。那么又在这。夹在这儿,OK,它是那个祖国妈妈。好,该分支实现。贝斯激素直接将质累累加到贝斯上。也即其他线程正在初始化,比如说正在初始化我们的C单元格数组呢,多个线程就正在更新这个被思值,OK,所以说这是一个兜底的,那么最后C数组不再为空,且可能存在三要数组扩容,那么就是我们刚才所说的总干的第一个二和三,新建和兜底的说完了,那么要说下面最复杂的这个K1,它呢,共计分为六大步骤,那们多个线程同时命中了,该怎么争强,该怎么扩容?好,下面我们就来说说最复杂的这个CASE1。
15:20
这种情况。
我来说两句