00:00
那么将下来呢,咱们今天讲的叫做就作叫做分支合并框架,那么我们说这个分支合并框架呢,它实际上是在这个专一点七以后出来的,对吧,所以说可能到现在呢,应用的并不是特别的广,那么之前给大家讲这个张八新特性的时候,是不是已经给大家提过了呀,我们但是张文芳是不是对他进行了一个改进了呀,对吧,很方便就能写出来,但是呢,我们可能目前来说,这个企业当中是不是还是基于1.7的呀,这个呢还是会对大家有帮助的,说什么叫做分富状准框架呢?就如同翻译过来的,那什么叫做分支合并呢?对吧,叫做分合并框架,说白了,那说公式增的框架的一个思想,就是说如果我有一个大任务,对吧,比如说一个大任务,就如同之前咱们举那个例子,我们说从一算到比如说这个一千一之间的数的一个累加,对吧,那这个时候呢,这这个这么大数的一个累加,这是不是明显是个大任务啊,那么我们通常。
01:00
我们说风扇的特点就是它可以把这个大任务拆分成是不是小任务啊对吧?然后呢,不断的往下拆,不断的往下拆是不是直到猜到不能再猜为止,然后呢,接下来呢,就再把一个个子任务,这个小任务的那个结果是不是来哥运算呢?注意这里叫做并行求值吧,指的是多个线程是不是同时的对一个个的小任务进行这个求值运算呢?然后最终呢,再把这些结果呢,进行一个个的合并,最终汇总成一个值,这个就是我们所说的fo join框架,那我说这个风扇框架啊,它相较于原来的线程,或者说普通原来那个线程值,它有个什么区别,或者说它有个什么特点呢?它的特点叫做就它有个叫做工作窃取模式了,对吧,这个模式呢,跟大家以前说过,我再给大家简单的介绍一下,我们说如果说传统的这种多线程或者是线程实。
02:00
的话,我们比如说这个呢,以我们这个四核的CPU为例,所以当我们把不同的任务是不是拆分到这一个个的线程上来执行,说一个个的到这个县城啊,一把我们的任务分配到这一个个的县城上来执行吧,我们说传统的县城时,它有什么特点呢?说同学们任务分配过来以后,对吧?比如说这都是一个个的任务分配过来以后,那我们说原来的线程涉及到一个什么问题呢?叫做阻塞问题,是原来的线程涉及到一个阻塞问题啊,那么说一旦说我把任务都分配到对应这个CPU的内核上以后,一旦某一个线程发生了阻塞,那么后续的线程是不是可能就进行不下去了,对吧?后续我们任务的线程可能是不是就继续不下去了,但是呢,与此同时,对吧,我们说其他线程,比如说这个线程核上的内,这个内核上的任务是不顺利的完成了呀,这个内核上的任务是不是顺利完成了呀,对吧,然后呢,这个上面是不是有可能。
03:00
啊,也阻塞在这了呀,对吧,阻塞这那这时候就造成了一个什么情况,就造成了一个结果,就是这个线程,这个线程是不是还处于忙碌状态,但是呢,这个内核,这个内核是处于空闲的状态啊,因此我们说虽然说原来的多线层能提高效率,能尽可能的利用飞镖的资源,但是一旦发生了这种情况,那么我们说其中两个内核是不是就空闲了,也就是说这个CPU并没有被我们更加合理的进行一个利用吧,因此我们说在JDK1.7以后,出了一个叫做for join框架,它底层采用的叫做工作窃取模式,说这个工作窃取模式一个什么意思呢?说他呢,把一个大任务是不是拆分成N多个小任务啊,然后呢,把不同的把这些小任务分别是不是都压入到对应的线程中啊,注意形成一个线程队列对吧,并且是双端队列了对吧,线程队列并且是双。
04:00
对列,那也就意味着说一个线程它从这个头就开始进行一个个的执行啊,对吧,先生的都是从上边呢开始一个个的执行,执行我线程队列中的任务,但是呢,我们说一旦某一个线程上,它在获取这个线程任务的时候呢,当获取不到时,是不是有可能阻塞呀,也有可能是这里边没有了呀,对吧?所以一旦没这个线性队列里边没有了,那这个时候它会怎么办呢?它会怎么样啊,是不去偷啊,他随机找一个是不是线程队列啊,从人家的队列那个末尾是不是偷一个任务过来再执行啊,是不通人家这个队伍呢,末尾是不是偷来去执行啊,对吧?那相应的其他的是不是也是这种道理,比如这个线程在获取任务的时候,获取不到了,那可能就意味着我们这个队列中是不是没任务了呀,那这个时候呢,他也会随机找一个线程,就到人家的末尾去偷一个呀,因此得到的形程就是人家。
05:00
正常的线程从上往下执行,然后呢,另外底下的是不是被别的空闲的线程是不被抽取啊,那这样的话,相较于原来的好处就是它更能进一步的去利用你C型的资源吧,因此效率会更高。对吧,那有同学说说,那那那他到底他那个默认用几个几个,我用了几个线程啊对吧,说我我的这个CP是不是有几核,他默认就用几个呀,那么呢,之前咱们用张VA8是看了一下这个效果,那么接下来咱们是不是用这DK1.7的for join框架完成一下呀,对吧,我们说自己写一个说一到比如说多少一个数之间的是不是一个累加操作呀,我们过来呢,我们试一试说计算盒,比如说来个叫做test fo join铺,对吧,对吧,Fo join语框架分支合并框架,那那这个时候呢,我们说自己模拟一个,那我首先创建一个类是不是用于计算,说一到指定一个数,一个哪项操作的呀,对吧,或者零到指定一个数,那么比如说我们这个就叫做fo join,呃,Sum吧,Sum c CU calculate对吧,LA对吧,开来个运算,运算呢,我们说这个类啊,它需要继承一个什么呢?继承是不是人家的。
06:16
样呀,对吧,叫做继承,一个叫做RECEIVE2个,其中一个叫receive task,一个叫做receive action,它们俩的区别就在于里边的实现的方法,Task是有返回值的,Action没有返回值,能听懂啊,是不是这点区别呀,对吧?那比如说我们要计算一个总值,我们是不意来个带返回值的呀,返回一个楞,然后呢,它让我重写里边的抽象方法,注意这是个类吧,这是个类啊,我们可以对吧,我们先先试试,然后呢,这里是不是给我来用黄线呢?它让我提供一个序列号,是不是表示可以被序列化呀,对吧,提供一个序列号,这个序列号什陌生们对吧?那么咱们先简单的说一下这个你我继承了这个receive plus的这个receive是什么意思?Receive是不是叫递归呀,是不是叫递归的意思含义,我们说这个大任务拆分成小任务,你说不断的拆,不断的拆呀,那你说不就递。
07:17
递归以递根列方式不断的去拆成小任务啊,递归的一个运算啊,那么接下来呢,我们就开始算,那我要算指定某两个数之间的一个总和了,那首先我比如说我这里来一个叫做long start,来个long end,我就从start算到end可以吧,那么注意我们刚才说了,你要猜你是不是一直猜到不能再猜为止,对吧,那不能再拆为止,你是不是意思你得设置个邻距值啊对吧,说猜到什么情况下,我说不再猜了呀,对吧?那比如说来个SP final London叫做s hold,对吧,Th hold s hold吧。
08:03
S code就是说临界值的意思啊,我注上的叫做临界值,临界值做搞定了,那么接下来呢,我给它搞个构造器吧,来一个叫做构造器,把这个呃,Long形的start什么的你是不是传过来啊,要从哪算到哪,我给它传过来this加等于start this.and等于嗯否令。那么这个时候呢,我们说这个几个数值我先在给它准备好,接下来我们是不是就开始拆分运算,拆分运算那在进行拆分的过程当中,我们首先要确定一下我们到没到达明确值吧,如果到达明确值我们还在拆吗?是不拆的呀,对吧?所以说我得判断一下,说if对吧,或者说我们先算一下long形的,来个length等于and减去start,说如果你要算的这个值要是小于等于三后的,对吧,这个是U。
09:03
到时候是不是小于等于这个临界值啊,那要是小于等于临界值说明还拆不拆了,那是不是就不拆了呀?不拆了我是不是就直接算个总和就完事了对吧?那就long形的some等于0L,然后来个负循环,AI是不是得等于start,因为从start开始吧,然后呢,小于等于and,然后sum加等叫做I,当上我这个I是不是也得是吧?是不是也得long形啊对吧?然后最后呢,运算出来这个总和往re return上上对吧?所以如果你到达的临界值,我是不是就直接运算总和啊,如果没到呢?那是不是猜呀,对吧?如果没到,我从句行进行一个拆分呢?对吧,怎么拆分?刚说递归形式拆分,那就是fo fo John some calculate吧,我比你说拆成,以这个图为例,我是不是拆成左右两部分呢,对吧,那我就往左右部分拆一个叫做left,对吧,又一个John。
10:03
对它然后从哪运算到哪,我首先比如说一到100的亿,我是不是给它拆出来,先拆成两部分呢?先算,比如说算算从零到这个,这个50亿,然后呢,五十五十亿,零一是这么读吗?00N1,然后算到100亿,然后接下来那50的计数还算多少,50亿,然后再再分成一零到25亿,然后25亿,对吧,再到一这个再到50亿,是这意思吧,就这么的不断的猜,不断的猜啊,一直翻到1万,当然这个临界值你是不是有的时候你得我临界值怎么能是零呢?临界值是不得1万呢,你猜到零了,实际上这个临界值你是不是可以调啊,实际上猜到1万,然后再进行合并,实际上也会影响效率,当然这个临界值的设定呢,这是需要用你的程序去做一些什么,这个测试是不是?哎,你得去平衡量一个临界值在什么情况下。
11:03
效率最高啊,对吧,因为之前咱们说的,因为你拆分它是不是需要时间,对吧?你把一个任务拆出两个任务,它也是需要时间的,对吧,说只有当我们拆分的这个过程大于你的执行时间的时候,你是不是才去拆呀,对吧?所以说临界值的设定呢,需要跟你实际项目的运行状况而定,那么这样的杠呢,我们说拆成中间,比如说一从零到100亿,我是不是先猜到零到50亿啊,我是不是得取个中间值,对吧?那就来个long的mid middle middle等于什么呢?比如说start加上and是不是除以二,除二可以吧,对吧,就是一个总和除二,除二之后呢,首先拆,从start拆到middle,是不是拆一半啊,然后拆一半,怎么个拆法?注意只需要调用这个left,点上join,那么这个时候它是不是就拆分了,进行叫做进行拆分,同时将是不是压入线程队列啊压入。
12:03
的入线程队列相应的你是在哪猜成右边右半部法,对吧,叫for join,这个拆成right,又一个,再来个book John,它这一次从middle你是得加一,不然的话中间这个middle是不是加重了呀,对吧,你得加一,然后呢,来再来个and,然后呢,Right点呃不叫fork呀,是不点fork叫拆分呢?这里是叫合并呢,对吧,For啊,点fork是不是进行拆分呢?对吧,这个也拆分,最后你说把拆分之后的结果进行一个合并,对吧?怎么个合并呢?合并只要return叫做left.join加上right.join对吧?就相当于是不是这个过程啊,Join的时候是不是就开始合并了,把它们的结果进行一个合并汇总,那这个就是。
13:03
它会递规的去进行不断的拆,不断的拆,直到拆到不能再拆为止,这就是for状框架,那接下来是不是用啊,那接下来呢,我们就用用我搞个main方法,搞个慢慢法,以后呢,注意我这个方式状框架它需要一个叫做for join to的支持才能执行是不吧?因为它是不是也要结果呀,所以说它得需要这个to持的支持才能执行for to是不是创建词啊,然后呢,注意我的这个类火是不是就创建这个对象,用一个它,然后我要算哪到哪,它是不是应该也是这个类型啊,但是我往上翻我的这个photo some ccate是不是继承了receive task,我们往上翻receive task是不是继承了focus join task,然后再往上翻focus join task employment。
14:03
Future所又回来了,我说为什么搞接口,人家专业工程师为什么设计接口目的数求扩展对吧?数求扩展呢?说这个future是什么时候出来的,刚才咱们是不是知道是不是1.5出来的呀,后来有了1.7,他说是对人家原来的接口是不是进行扩展功能的扩充啊,怎么扩,是不是实现接口接的继续往下扩,这就是接口的一个叫做面向接口编程的一个特点嘛,所以说呢,现在呢,按照它的函数以后,实际上它给我返回的是一个for join task,并且能带返回值的task ctrl shift o导向包。嗯啊,我说得有三个导器啊,从零算到100122345678,这是一个亿吧,是一个亿啊对吧,一个亿,然后接下来是不是就执行啊,执行呢,只需要通过说不你得用破的这个Li啊,破点叫做e work,它是不是需要一个photo状task,咱们这个是不是就是刚好是个task,完事了以后,它是不是给我返回一个总和,对吧,拿到总和打印输出一下就不看看对不对啊,这个结果咱们是不是一眼就能看得出来呀,什么500500啥的有金。
15:21
运行一下试试。是不是有效果呀,是有效果计算完了,那这就是我们所说的for join框架,那么接下来我也知道大家是不是也想测测呀,以前我们说用的张法对吧,那明显扎法要是大值块是不是小值。不行啊,小直径for没法比吧,那咱们也来一个,就做sum等于0L,然后来个for循环,从这个也是个long,然后来个0L到这叫一个E吧,你是不是小于等于啊,然后来个叫做S加等I,最后呢,再来个呃,Sit out下I some是不就完事了对吧?C out下some,然后这个时候呢,我们要计算时间,嗯,还是用原来的,还是用章法呀,叫做instant对吧,Instant点上now对吧,返回一个instant的实例吧,对吧,叫做start,相应的呢,再来一个instant的and等于instant n s instant.now对吧?然后最后比较两个时间呢,那个是怎么说是Du呢Du。
16:39
我reason点上是不between呢?看start和and他们俩的是不是点two million毫秒毫秒可以了吗?那这回试一试,先看看普通后一个亿右键运行是不是又又跟咱们上次结果很很像的是吧,对吧,几乎一样,那么这样的话呢,我们在上边这个看看跟我们自己写的这个BB对吧,跟我们自己写的BB右键。
17:10
点点错了,点错了右线是不是张螂可见的,这是我的默认方法对吧?是这效果不用,哎这还是啊这问题上说吧,因为说你拆分的他是需要时间的,对吧,你拆分是需要时间的,而我的放循环,那是不是调用的相对来说比较底层的呀,在效率实际上还是挺高的,那么说什么情况下我们要用方SH呀,我们说当我们拆分的这个时间大于你串行的这个截行时间的话,我们是不是就猜,那因此现在效率没有它高,得到的结论就是我这个数啊太小,当然可能性有两个,一个是我的临界值是不是太小了,对吧,一个是我的临界值太小,也有可能是不是我这个数值太小,对吧,那我说再来点零啊,再来点零,100亿啊对吧,100个亿,那这个时候呢,先看我们自己写的吧,对吧,然后。
18:11
同时咱们要看看这个CPU的利用率是吧,看能不能利用的上右键运行。标起来了没,80%是不是完事了,那这回是不是1996了,这是100个亿吧,那这个是这个是不是也是100亿啊对吧,我CTRL为一下,那这样的话呢,看看我们说普通的for是不是单线程啊,这是啊执行。两秒差不多过了吧,闭合三秒对吧,但是是不是有效果呀,咱们这个逻辑毕竟还是简单吧,对吧,毕竟还是比较简单的,那要是500亿的话,那差别是不是又大点了呀,那你们想不想跟张发那个比比,是不是也可以比比啊,对吧,叫y test,二说JAVA8呢,我们是不是long sum等于long streamam点上瑞。
19:05
点叫做read close,这个就是带带收尾的对吧,对吧,Close带个带这个的带能有结束,有开始,有结束没完事,所不你得先给它切换成并行流对吧?这方点上叫做para,在点上叫做reduce,可以吧,来个0L到1LONG的some是否定了,最后呢S下对吧?这是找法八新特性对吧?那这样的话,我们说他跟我们写的谁快谁慢呢?你们觉得那时候是应该是人家写的快呀,毕竟人家是不是底层已经封装好了呀,算法是不是肯定比我们都牛一些呀,对吧,100亿知八右键。嗯,运行行义务这确实快对吧,对吧,它的利用率更高啊,所以他写的这个CPU的利用率呢,比我们的还高,我们刚才可能飙到百分之八九十是吧,大家69这个还太小对吧,还太小,我给来个500亿吧,500亿看他的CPU右键运行。
20:20
是报表了是不是啊,对吧,那这是500亿对吧,那这是张八巴的特性,那我们应该比他差也差不了太多吧,对吧,那我们右键试试我们自己的执行,看我们的对,看我们的CPU。我这是不是卡住了66%,83 92,对吧,是不是差两秒啊,差两秒我们也没有啥用啥特殊的算法,而且我的我们这里是不是也有点,比如说有点那个自动装箱的过程呢?你差这个两秒你是不是可以优化的,是不是可以进行优化的,你看我这是start,这是不是基本类型啊对吧,你最后返回的是不是包装类啊,你最终的结果你是不是肯定会有个装箱的操作啊类似的呀,对吧,都得有,那你说这两秒的差距肯定是有的,那你说我现在要跟普通的缝比比他强不强吧,那是不肯定比普通都强啊,对吧,那我们就过来跟普通phone比比,普通po算500亿,那是不是能得送到下课强,诶咱们上次算没有没有啊对吧,也没有,那么哎,我们是我们是1万,他大概3万是3万毫秒啊,大概30秒,对少15秒,那不能吧。
21:41
对吧,所业活动报500亿啊,15秒啊,对15秒,那当然咱们这个内容还是毕竟少说为什么之前这个为什么张要八要对这个复合状语进行改进呢?原因就是你看咱们写起来麻烦不麻,这叫麻烦啊,你是不还得算你自你自己在拆分的过程中,你说咱们现在逻辑简单,你可能拆成两半,可能感觉还好,但是要是以后我们说算一些复杂的逻辑的话,你说你给他拆,拆着拆着,我估计自己是不就拆蒙圈了,是不是关不上他可能啊,但是不行啊,1.8现在还是不行,他病情里现在1.8,因为企业当争还没用,并没有那啥嘛,对吧,好了,那这个先到这,我先把它报。
我来说两句