00:00
接下来呢,咱们继续往下讲,一个叫做并行流,那么之前呢,已经给大家介绍过了,我们说张喇啊包它的速度变高了,那么其中一个它就是这个并行流,它也起到了一个很关键的作用,使我们的程序很容易了就能切换成多线程,而且更能利用CPU的资源。那么在讲定从流以前呢,我们首先得提另外一个框架,那个框架呢,就称之为叫做fo join框架,说这个photo框架,先说说这个photo框架是什么意思,说所谓的这个photo,它就是在必要的情况下,将一个大任务进行拆分,拆分就是就爆开啊,对吧,进行拆分,拆分成若干个小任务,拆到不可再拆为止,然后呢,再将一个个的小任务运算的结果进行join,是不是合并呢?合并进行汇总,什么意思呢?比如说现在呢啊。
01:00
锁屏了,现在好了吗?好了什什么意思呢?就比如说现在呢,我有一个大任务需要完成,对吧?那这个单位任务呢,它如果说以单线程的话,这个任务那是不是很消耗时间呢?对吧?比如说我现在要算一到100亿之间的一个数的累加,那你就想想要是单线程的话,那是不是效益极低,对吧?那比如说类有类似于这样的大任务的话,我们就可以把这一个大任务先拆分成是不是两个子任务啊,对吧?如果说子任任务还可以再分,对吧?比如说我们可以设置一个临界值,什么情况下就不分了,对吧?如果在什么情况下,那我是不再分呢?再分成一个个的子任务,然后一一直分到不能再分为止,然后把这一个个的子任务压入到线程队列,也是压入到你CPU的那个线程队列当中去,然后呢开始执行,执行了之后每个子任务是不是都会产生相应的结果。
02:00
好呀,那么求出最得出对应相应的结果以后,然后再把这些结果进行join,是不是合并呢?最终合并成一个最终的结果,那么这就是一个方算,就是拆分合并,其中这个方范框架它早在这个是1.7的时候就已经有了,但是呢,它的使用呢,相对来说稍微的复杂一点,所以说呢,应用的并不是特别的广泛,但是方障状框架的这个核心它还是非常好,它的效率高,我们说为什么它的效率高呢?它与传统的线程到底有什么区别呢?咱们举个例子就明白了,比如说呀,我们说我们说多线程,所谓的所谓的多线程呢,是不是就是把我们的任务分配到CPU不同的核上,也就是不同的线程上啊,对吧,CPU不同的线程上进行执行对吧?比方说比如说以四核CPU为例,比如说这是我四核CPU,这是不是都是一个核。
03:00
啊,说白了是不是就是一个个的线程呢,对吧,然后呢,说以四核CPU为例,如果说是传统的线程的话,我们是不是以多线程的,如果多线程完成任务,是不是把这些线程都给它分配到一个个的CPU的这个线程盒上执行啊对吧?比如说这是一一系列的任务,对吧?这是一系列的任务,这是一系列的任务,然后在这个多个线程在CPU不同的核上进行执行。那么如果说传统的线程的话,它存在一个什么问题呢?我们说如果是传统线程的话,它是不是每一个任务有可能会阻塞,阻塞,我们说你每个线程执行的时候什么时候执行,那是不是由非平衡时间片给你分配执行时间的,当这个时间段用完了以后,CPU会强制剥索,你的执行前是不是交给其他的线程去执行啊,对吧?那这是一方面,比如说让你使你阻塞的情况,那是有很多种,对吧?那都有可能阻塞,那那如果说一旦某一个线程上某一个线程发生了阻塞情况的话,它会造成一个什么结果呢?它就有可能,比如说当在这个核上执行的这个线程一旦发生阻塞的话,那么在这个线程上的其他线程还能执行吗?就不能执行了,只有等这个线程执行完了以后,在这个河上的其线程是不才能执行。
04:30
他才能执行啊,但是在这种这个同时,与此同时有可能会发生什么情况,就是在这个和上的线行啊,它顺利的执行完了,这个和上的线程呢,它也利的执行完了,而偏偏只有这两个,刚才是不是阻塞了呀?对,堵塞,那么当阻塞过去之后,那它是不是依次往下执行了,但是在执行的同时,另外两个线程怎么了,是不是没任务了,没任务意味着是不是就空闲了,而另外两个线程上,这是不是线程队列还在这排着呢?这就意味着造成一个结果,就是你说没有很好的利用CPU的资源,对吧?另外两个线程处于繁忙状态,忙碌状态,而中间的这两个线程没有任务执行,处于空闲状态,也就是说这两个CPU的资源被我们白白的给浪费了,因此想想的话,那是不是也影响我们的效率啊,对吧。
05:30
那这就是传统线程存在的问题,也就是我们原来用的那些线行时都是这种情况,看到吧,那么咱们现在的这个发框架,它是怎么做的呢?首先当我们说了,我们发状指的就是把一个大任务是不是拆分成若干个小任务啊,然后他会把这若干个小任务都压入到对应的县城当中,然后形成一个个的县程队列,对不吗?对吧?他会把一个个的小任务压入到每个CPU的每个线程中,对吧?默认就是你CPU有几何,它是不是就利用几个线程啊,对吧?默认都给你压入到对应的线程当中,形成一个个的线程队列,然后形成线程队列以后,它有一个什么特点呢?也就是它的核心叫做,这个叫做叫做,它有个叫做工作窃取模式,我们说发国家的执行采用的是工作窃取模式。说什么叫做。
06:30
通过器举的我们说当执行新的任务时,它可以将其拆分成更小的任务执行,并将小任务是不是加强到线成队列啊,然后再从一个随机的线程队列中通一个,并把它放在自己的队列中,说什么意思呢?比如说如果说现在,当然我们说每一个线程上是不是都形成一个线程队列啊,实际上在每一个线程队列都是双端队列,知道啥叫双端队列吗?哎,是两边都都有口啊,那意思啊,那么还义方向有时采用的线程叫做工作窃取模式,说什么叫做工作窃取呢?指的是比如说如果说我这个线程上执行这个线程队列,它执行的如果快,或者说什么意思呢?就是当我这个线程在获取对应任务时,获取不。
07:30
到了是不是对吧?可能有很多种原因,比如说这三门线程队列没有任务了,是不是就获取不到了,对吧?那如果说当这个线程获取对应的任务时,获取不到时,他会怎么办呢?他会随机找一个线程的线程队列上的这个任务偷一个,比如说它随机找到到找到了,它找到它会从它队列的末尾偷一个任务来执行,对吧?偷对吧,是不是通出来了,通就执行,那与此同时,这个线程是不是从上执行啊,而这次它最下边这个是不是被另外一个线程偷走了,对吧?那与此同时一样的道理,这个如果说这个线程在获取任务时获取不到了,也就有可能很大的可能,是不是就这个上面的任务执行完了呀,那这时它不会闲着,它会随机找一个线程队列对吧,线程队列的末尾是随机找啊,对吧,然后再偷一个执行。
08:30
那么想可想而知,那利用这种情况的话,它是相较于原来的椭圆形,它更能尽可能的利用你CU的资源,对吧?使我是没有空闲状态的cepo啊对吧?没有任务了他就出去偷路对吧,自己没有就去偷别人这句话有点不太好听是吧?但是它这就叫工作窃取模式,听懂吧,对吧,偷的不是别的,偷的是工作,听懂吧,对吧?那这就是我会告诉你的原理,因此说风它效率高,因为它效率高的方式,它更能尽可能的利用CPU的资源,这就工作器体能听明了呀,对吧?那么也就说那实际上在加VA7上就有了这个口照,为什么呢,它没有被广泛的应用呢?因为它实际上写起来稍微的有点复杂,那么过来咱们是不是试试啊,原理都丢出,嗯,那么过来试试说这个方向扇的框架怎么去用呢?对吧,那我们写一个。
09:30
比如说呢,我们就实现一个数的累加操作,行吧,对吧,是一到多少个亿什么的累加,那比如说呢,现在我就创建一个比如说叫做fo Joy,叫做calculation LA,对吧,是不是这么形的LA calcul对吧?然后呢,运算我们说你文使用这个photo框架的话呢,它必须继承一个类,叫做extend extend,谁呢,叫做iveive re,嗯,怎么没有反应了啊,这呢,REC。
10:16
Re r对吧?这里有叫receive action和task,就这里这两个有什么区别呢?一个是里边的方法没有返回值,X是没有返回值的,Task是有返回值的,就是里边的那个方法,一个是有返回值,一个没有返回值,就这个区别能明白吗?那我们说要个有返回值的,那返回什么呢?总和累加总和我说返回量啊,对吧?然后呢,这里头有个抽象方法,我们实现一下,然后注心角,它这个呢,要求你它有个黄线,要求你是不是得被序列化呀,提供个序列号,然后我们目的是完成一个累加,说从哪加到哪,我首先来一个型的start吧,然后再来个long型的and,应为注意so join是不是要拆分的,对吧?你三分,你是不是自己得写算法,你怎么拆,按照什么规则去拆,对吧,拆分到什么情况下不?
11:16
拆了,这是不是都得你自己去算算法去解啊,对吧?那比如说我这里来个叫and,从哪加到哪,注意在什么情况下不拆了呢?我搞一个临界值,比如说static final的in吧,Long long的,比如说res s hold是不是临界值啊,临界值为1万,就是我不断猜,比如说我要计算一到100亿了,那我就不断一半一半的猜啊,先从一到50亿,然后50亿到100亿,然后呢,一到50亿是还能再猜啊,那然后什么一到25亿,然后25~50亿,然后呢,那一到25亿是不是还可以再猜啊,直到拆到一半为止,那时候形成老多很多个小任啊,用吗?然后形成线程对列,一个个的都加到你的线程去,形成线程对列,能明白这意思吧?嗯,那我就猜,然后呢,最后这个呢,我要判断一下这个临界值,也就是and,如果and减去star。
12:16
它得到是不是得到一个lengths啊,就是long形的lengths,哎说如果说你的这个lengths如果小于等于s food是不是也就是到临界值了,到临界值我是不是就不能再拆了呀?对吧,不能再拆什么呢?不能再拆我就计算和了呀,我就来个long的sum,然后等于零,然后来个负循环吧,是不负循环去累加呀,I等于是不从S2开始,然后来个I小于等于吧,小于等于N的是不是到末尾那个结束啊嗯,这个我得给成改成了,是不是浪了,然后来个叫sum加等I的值,最后呢,我把这个总和是不是来个return叫做sum,把这总和返回,这是如果到达临界值,我是不是就开始加不到达临界值啊,我说要拆啊,拆成一个个子任,那就是else,如果是N,我是不是拆值任务拆成子怎么拆呢?我要创建叫方。
13:16
放个照,开个类,也就是我这个类的实例吧,是不是创建这个实例这样吧,先问问大家这句以后啊,这个单词翻译过来是什么意思,Receive,对吧?Receive什么意思?哎,是递规啊,递规的意思对吧?所谓的风join,它是不是递归在不断的去拆啊,对吧?递归拆,所以说如果没到临界值呢,我就给它再去拆分,比如说这叫left,拆成两个吧,左边用一个book join,好,嗯,我得有个构造器啊,来个构造器,来个构造器public book join calculate,然后呢,受理船呢,从哪开始算呢?对吧?浪long start,再来个long and,然后呢,我在这里呢,this.start等于start this.and等于。
14:16
And,那么我这里呢,第一次我想想啊,我们是不是一半一半猜,一半一半猜,那也就是start,我加上这个N的是不是起始值和末尾的那个值啊,我加上除以二,这是不是就一半了,一半那就来个long的,比如说middle是不取个中间值,那第一次呢,我从start开始到到middle吧,说到middle middle到middle结束,然后呢,我我来是不是来个等会啊,这首先我是不是就开始叫做fo,是不是就形成了一个拆分呢?对吧,这叫拆分成子任务叫拆分子任务,子任务同时子任务,然后同时呢,压入线程队列,是不是就是直接压上全主意力了,对应的形成对力,那这叫做folk,首先拆,然后fo拆了之后另外一个是不是还得拆,对吧,还得拆成另一个fo take例叫I。
15:16
诶,这一对吧,然后你一个book Joy calculate,这一次从middle middle得加一吧,不然middle是不是加重了对吧,到and,然后呢,Right点也for对吧,然后拆完之后你不是得合并呢,把for之后的结果你是不是一个个的合并对吧?那合并的我们是不是累加总和啊,那就left点叫做join,叫合并了,加上right.join对吧,最后这个return我就不要了,那么这样的话呢,我这个就写好for否个状语框架,不断的拆,不断的拆。
16:00
是不是逻辑上稍微有点复杂,咱们这写的还是最简单的呢?对吧,你说一到一到10万个累加对吧?实际应用中我们说能写这么复杂的逻辑吗?不能,我们说际用当中,比如说要是按照大数据来讲的话,我们只有大数据的时候可能会用用它,比如说我们说就如同刚才咱们举了个例子一样吧,就说我们说可能写一个程序是不是扫描文章啊,扫描了所有的文章,然后从文章中找出一个热搜关键词,那你想那文章要是过多,那网上的百度上文章多了去了,你一篇篇搜,或者一个论坛上的文章那时候多了去了,你用片片搜,那这个时候用for状是不是很好,对吧,对吧,你多个线,你面同时去搜搜不同的文章,然后找热搜关键词,然后最后最终的在join那是不就可以了,那种情况下就可以适合用服状,但是你写起来可能稍微的就复杂点。对吧,但是它效率确实是高,好了,那么先先继续往下,这个时候我的这个逻辑我就写好了,写好了我是不是要用啊,那这时呢,我创建个叫test book join语行test for join语,注意这个for join它的执行呢,它得需要一个词,我用at太短,它得需要一个focus join pull for join线程池的支持,叫focus join pull吧,对吧,然后来个pull,等又一个for join pull,对吧,它是不是得有个先程词的支持啊对吧,来个值,然后呢,紧接着呢,注意我这个,我这个时间类是不是继承它呀,类继承它,那么实际上呢,它们再往上是继承的for join task是不是一系列啊子类关系,那这时呢,我就来个叫做fo join task,对吧,然后返回来是不是有返回之状啊对吧,这个叫task,等又一个fo。
17:57
Join就是我刚才写的这个,我要计算哪呢?从零嘛开始,我要计算112345678,这是不是一个亿,哎,一到一个亿的累加,然后之后一到一个亿之后,我是不是就开始执行呢?叫做pull.submit me把task传过来,与此同时它会给我返回一个long,什么sum值啊,不对,不是萨呀萨是不是没反问值啊,叫做invo,对吧?Task传过来是不是用反问值上最终合并的那个总和,我sit out向上可以吧,对吧?是这样写的,那首先运行一下,看看效果行不行,直行5050,这明显结果是对的呀,对吧,别的不认识,这几个应该是认识。
18:44
那么这时咱们数据运算下时间对吧,看看它到底用不用多核C,这个C中的多个和对吧,多个线程,那就是让的start等于C中点current ten minutes对吧,嗯,实际上既然是二八,我也想用张二八的计算时间用一个用一个用一个,那就怎么用一个instant instant对吧,嗯,ST对吧,点上now对吧,这个呢,实际上也是用于计算时间桌的,得到一个呃,Instant对吧,Instant start,这时呢,我再来个instant and等于instant,哎,No,点那对吧,然后最后呢,我们可以用什么呢?叫做the reason the reason,点上between对吧,然后第一个呢,叫做。
19:44
大和呢,End end对吧?然后我们可以计算一个盖了个什么呢?这是秒,这是纳秒对吧,纳秒秒吧,行,纳秒是不是也行啊,多少纳秒都可以啊,来个叫耗费时间为加上这纳秒啊,先试试效果,右键运行这么多纳秒吧,这么多闹秒是不是不太好看呢?那get second这是不是秒啊,那这是零,你们想要啥?想要毫秒叫to不行,它只有那秒,那是分钟啊这呢这呢毫秒哎,这是毫秒,这是毫秒对吧,毫秒。
20:38
是不也38毫秒对吧?这还没快,这没快啊,我给大家再试,没试完呢,这个是我们用photo join框架吧,Join框架框架我们说不是来个最基本单线程的比一比对吧?那我们说搞一个后循,普通的后循环呢,来个TEST2,我们说来个普通的负循环,叫普通负循环,完成一个这个操作,那普通的负循环首先我得有个long的sum,初始为0L,然后后循环对吧,后循环I等于零,I小于,这是一个E对吧?那这时候我能给它换成了,然后来个叫做sum加等I吧,然后呢,C萨呀,最终是不是总和啊,然后是不是也计算一下时间,用它计算,然后这俩我copy过来,这没问题吧,对吧,就可以,然后呢,大家可以稍微的搂一眼啊右刚才是多少呢?
21:39
一百三十八幺三八,那这个呢,我试试右键运行,哎,这个等会加小一点,等我还没试完呢,你34他说对太对,实际上是空管,实际上正循环的,它实际上算是比较底层的码啊,它实际上直接是调用的底层,它的效率实际上是相对来说比较高的,再一个我还没说完,那你听我说完,那再一个是什么问题呢?注意如果说我这个数值过小的话,你拆分要不要时间,需要时间呢?你不断说它明明是一个三线能很快就能完成了,你还不断的拆分,不断的拆分,把它拆分成都分成了,拆分是需要时间的,所以说呢,如果拆分的这个时间要是大于。
22:39
在延长的时间,那在这种情况下,我们是不能用方面,那什么时候用,哎哎,速度越大,它体现的效率才能越高的,哎,所以说这个临界值个设率是不是很重要,这是第一个换上和第二个有多高,你是不我现在一个亿不够啊,我再加两零是不是100亿,这个加两零啊,100亿算是100亿以后相等对吧,是两人这不是100是不是都加了100亿啊才那个没问没问题啊,这个就可以应该能试的出来了,因为这指太大了,是不算不出来了,这是2016啊对吧,那再看这个,这是咱线程3135对吧,3135,这是不是就明显了呀,对吧,就你输出。
23:39
大的话,你数据率越多,它包个照应体现的才明显,对吧?不然的话,你如果数值过小,你说明明就一到100的之之间的累加和一瞬间就完事的事,你还得给它拆拆拆拆成拆成很多小任务指任务,那拆分是后面时间的吧,对吧?那你说再大点呢,别来零,别来了个零了,来个零估计够我这电脑够呛,别给我烧了,比如说我再加个五五百亿,这就500亿吧,五百亿五百亿执行,我让大家看看这个东西就行了,看这CPU的利用率对吧,是不是我八个线程全用上了,它默认就是你有几个线程他就用几个,哎,这叫99260是不还能看到效果呀,这是500亿的效果了,那么再看这个对吧,看看这下9000 9000是九秒啊对吧,那这时啊,一他这个500亿应该也有也有也有效果。
24:39
CPU没用,CU百分之十六十五吧,它不一定是切零,我们说线程它是不是得切换呢?哎,它也会切换,但是有效果了,是不是就是15秒了,对吧,对吧,也多,那你要是再你说再大点呢,210行行加加个零听你们的,那就没必要了,就这样吧,就这样不对呀,咱这按理来说他应该到达到达90%以上上还说1000亿,咱们刚才说到80%啊,对吧,他是利用的还是比较明显的,这是。
25:39
啊,介绍1000亿吧,这是不是也是1000亿呢?对吧,那这个好像这1000亿好像没有效果了吧,不知道他能不能等到这个时候,一千一现在十秒过了,19秒不能怎么样,是不是过了对吧,对吧,大家这能不能看到时间吗?这不明显,19秒过了,他就这应边执行是吧,咱们都不管了,所以说通过这个来呢,不出这种框架有没有用,说明显他们更能尽可能利用CPU的资源呢,对吧,哎,完事了,是翻倍了对吧,翻倍了啊对吧,翻倍了对吧,所以说方度这的框架效率确实高,数据量越大,它体现的就越明显,对吧?当然还有一个需要注意的地方,就是你这个临界值,你的设定它是不也得注意。
26:39
哎,稍微的大一点啊,对吧?以我这个例题来看的话,它可以稍微的大一点,对吧,对吧?所以说通过这个来看,风和状框架它还比较用,对于大数据来讲,你说它更有用了,就是如同我刚才举那个例子一样,对吧?你在大数据你搜索个网络热搜词对吧?你一个论坛那么多篇文章,你要是单线程完成是不是效率低啊,你这时候选择用photo join感觉就很好,但那你什么应用的?呃,并不是极广,或者并不是特别的火爆,对吧?包括你们现在是不是有些同学都不知道啊,为啥?就因为操作起来非常的麻烦对吧?那么你们已经看到了,现在是可能有些同学感觉还是有点懵的,对吧?所以说在JDK1.8加VA8以后,他们对哎,改进了,对这个并行流进行了一个提升,提升成什么样呢?注意看扎VA8并行流并。
27:39
流,并行流,我们说在这八中,我们想要完成这个操作,我们只需要干怎么办呢?说三,大家还记得有个叫做long streamam吗?就streamam呢,Long的表达表现形式,它里面是不是有这个装向好的值啊,对吧,那long streamam它多了一个方法叫什么呢?叫做叫做叫做RA close,就是能生成一系列一个连续的数,听懂了对吧,这就是long long in double的特点,我从零是不是生成到到这1000个亿啊对吧,1000亿,然后我要从零到1000亿,是不是进行个累加,怎么累加,直接reduce可以吧,对吧,Reduce,然后从零一直到in到sum,是不是就累加了对吧啊long,对long long sum说long sum,这是不是就叫累加了,对吧,但是。
28:39
你在这是跟我们原来写的一样,这叫顺序流流是不吧?这叫顺序流,顺序流那它是单线程么?那效率肯定是低的,所以说我们现在是不是想让它变成并行流,那你只需要在这里用一个方法叫做还经算的方法,叫做pilo,看到么?我们的集合提供东西叫parallel string吧,那流上直接提供了一个方法叫做parallel,对吧?或者说我们说可以通过方法parallel和这个方法,它可以任意的去切换顺序流和并行流,现在是PI,是不是就并行流啊,顺序流你就再调用这个方法就完事,看到没?然后是不是计算时间。
29:21
是不是计算时间对吧?这是开始,这是结束,是这意思吧,时间去掉,这是不是1000亿啊对吧?1000亿没问题吧,又见运行什么情况,1000亿,这不给面子1000亿,刚才我上的一千一是19秒吗?哎,先看我这CPUCCPU定上是速快了,吓我一跳,怎么这么半天呢?呃,刚才看到CPU了吧,这个已经完事了啊,这是刚才没过去是不是1%啊,重来一次,重来一次,右键执行,这直接就爆了,爆表,这还是他底层,就是意思是他底层呢,比我写的要好一些。
30:21
对吧,对吧,利用率更高一些,那这样的话,这次完事是还16秒,还慢了点,但是是不是差不多呀,对吧,差不多就在这个附近,但是无论如何肯定是比单线程要高很多,这就是知道吗?对吧,以后你说现在你要用招说来个大数据的处理,那容易不容易啊,对吧,直接来个parall map reduce搞定,不是不是搞定了对吧,所以说这法一定是未来的一个趋势,你们搞不定吗?是不是这么,现在就是这么简单的对吧?好了,那么以上呢,就是并行流虽但是大家要注意,虽然说张高我们用PA,实际上底层是什么东西啊,是不叫photo join呢?对吧,底层就是photo join,那刚才我们说了,那说底层是photo,我们说那你photo执行的时候是不是得有个风。
31:21
放破了对吧,那么实际上张发对它做一个什么更新呢?你没有这个方位作用破对吧,再张发以后你没有它实际上也可以了,可以了,怎么用呢?只不过他现在给你提供了一个叫做公共的作用和作用值,看到没?现在已经有个公共的值,这个值就是符往这种完成符合双向值,听懂了对吧?那这样的话,你就可以任意的通过拍的方法去切换并行流或者是顺序流,这就是否合效用的三八的并行流。同学们是不是挺好的。好了,那么F。
我来说两句