ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

16.如何使用ForkJoinPool?

2022-03-28 21:01:46  阅读:195  来源: 互联网

标签:分割 16 ForkJoinPool 如何 任务 线程 起始值 编写 100


 

 

 

如何使用ForkJoinPool?

 

 

 

 

本节来学习如何使用focusjoinPool,更高效的执行大任务。focusjoinPool是一个采用ffocusjoin框架的线程池,

 

 

 

 

 

它继承自abstractExecutorservice,

 

 

说明他拥有线程池的基本功能,比如说和一般线程池一样提交任务,关闭线程池等等操作,这些从它的uml类图中也可以看得出来,

 

 

所以大家按照和之前使用线程池一样使用focusjoinPool就好了。接下来介绍几个与之相关的类。首先是focusjointask,看到类名中带有task,大家一定会想这是不是用来提交给focusjoinPool线程池的任务,他的确可以,但他的职责却相当于future。


任务最终结果是从这里拿,我们真正想要提交任务的话,是通过他的两个子类,一个是RecoursiveTask,他的职责相当于callable,用来执行有返回值任务,另一个是recursiveaction。他的职责相当于runnable,用来执行无返回值任务。

 

 

下面我们要编写的例子是从1+~100,是一个有返回值任务,所以需要使用RecoursiveTask。在编写代码之前我们先来看一下,从1加~100的ffocusjoin流程图是怎样的,这个可以帮助我们理清编写思路。首先是将从1加到100这个大任务分割成两个子任务,一个子任务是从1+到50,另一个子任务是从51加到100,我们可以看到任务是从中间分割的,所以我们待会可以通过取中间值的方式来分割任务,继续将2个子任务分割成4个子任务,每个子任务计算25个数字之和,还可以继续往下分割,将4个子任务分割成8个子任务。 

 

 


接下来就是执行这8个子任务,然后合并子任务的结果,直至合并出大任务的结果,至此大任务执行完成,

 

 

从中间画一道分割线。上部分是在分割任务,下部分是在合并结果,

 

 

下面编写示例代码,编写一个任务task。继承RecoursiveTask是带泛型的可以指定任务结果的类型,从1加到100的结果是数字类型,所以我们指定泛型为integer,重写compute方法,分割任务和计算的代码都写在这里,定义一个int类型的属性start,用于记录起始值。 


从1加到100,1就是起始值,再定义一个int类型的属性end,用于记录结束值,从1+到100 100就是结束值,再定义一个映射类型的属性temp用于记录临界值。什么是临界值?就是一个子任务里面有多少个数字,比如说这里的10表示1个子任务里面有10个数字,你也可以理解成,以10个数组为单位分割1个子任务,重载构造方法用于初始化起始值和结束值。

 

 

接下来编写compute的方法,我们先来写计算的代码,再来写分割任务的代码,用结束值减去起始值的结果去和临界值比大小,如果小于临界值,说明任务无法再分割,可以开始计算,定义一个int类型的局部变量sum,用于记录计算结果,使用for循环计算任务中的数字之和,接着返回计算结果,至此计算部分的代码写完了,

 

 

再来编写分割任务部分的代码,首先取中间值,将任务从中间分割,取中间值的方法就是起始值与结束值的和除以二,这样将大任务分割成两个子任务。 


其中一个子任务是计算从起始值到中间值之后,调用fork方法将子任务添加至线程池执行。另一个子任务是计算从中间值加一到结束值。为什么要加一?因为中间值已经归前一个子任务中,所以这里要往后移移一位,之后也是调用fork方法将子任务添加至线程池执行,最后调用子任务的join方法合并执行结果,至此compute方法编写完成。整个任务也编写完成。接下来执行该任务,首先将任务串联出来,并指定起始值和结束值,分别为1和100,然后创建focusjoin线程池,接着调用submit方法提交任务,接收方法返回值,再接着,调用get方法获取执行结果,get方法有异常抛出,使用try---catch将其捕获,紧接着输出任务,执行结果写上finally代码块。 


在finally代码块中,要用shoudown方法关闭线程池,

 

 

 

 

 

至此main方法编写完成,整个例子也编写完成,

 

 

 

 

执行程序观察执行结果。从执行结果来看,程序输出5050,

 

 

 

 

 

计算正确,大家可以试着将结束值写得更大一些,在和普通计算方法做比较,看谁计算的更快。

总结

最后总结一下本节内容。本杰介绍采用ffocusjoin框架的线程池,

 

 

 

 

 

 

 

 

focusjoinPool它的作用及用法,这里就不再赘述了,在实际开发中我经常拿它来执行计算量大的任务,或者是数据量工作量很大的任务,这种将大任务拆分成一个个小任务的做法,它的工作效率远远超过一个线程执行大任务的效率。 

 

 

附录:

笔记完整文本:

本节来学习如何使用focusjoinPool,更高效的执行大任务。focusjoinPool是一个采用ffocusjoin框架的线程池,它继承自abstractExecutorservice,说明他拥有线程池的基本功能,比如说和一般线程池一样提交任务,关闭线程池等等操作,这些从它的uml类图中也可以看得出来,所以大家按照和之前使用线程池一样使用focusjoinPool就好了。接下来介绍几个与之相关的类。首先是focusjointask,看到类名中带有task,大家一定会想这是不是用来提交给focusjoinPool线程池的任务,他的确可以,但他的职责却相当于future。 任务最终结果是从这里拿,我们真正想要提交任务的话,是通过他的两个子类,一个是RecoursiveTask,他的职责相当于callable,用来执行有返回值任务,另一个是recursiveaction。他的职责相当于runnable,用来执行无返回值任务。下面我们要编写的例子是从1+~100,是一个有返回值任务,所以需要使用RecoursiveTask。在编写代码之前我们先来看一下,从1加~100的ffocusjoin流程图是怎样的,这个可以帮助我们理清编写思路。首先是将从1加到100这个大任务分割成两个子任务,一个子任务是从1+到50,另一个子任务是从51加到100,我们可以看到任务是从中间分割的,所以我们待会可以通过取中间值的方式来分割任务,继续将2个子任务分割成4个子任务,每个子任务计算25个数字之和,还可以继续往下分割,将4个子任务分割成8个子任务。 接下来就是执行这8个子任务,然后合并子任务的结果,直至合并出大任务的结果,至此大任务执行完成,从中间画一道分割线。上部分是在分割任务,下部分是在合并结果,下面编写示例代码,编写一个任务task。继承RecoursiveTask是带泛型的可以指定任务结果的类型,从1加到100的结果是数字类型,所以我们指定泛型为integer,重写compute方法,分割任务和计算的代码都写在这里,定义一个int类型的属性start,用于记录起始值。 从1加到100,1就是起始值,再定义一个int类型的属性end,用于记录结束值,从1+到100 100就是结束值,再定义一个映射类型的属性temp用于记录临界值。什么是临界值?就是一个子任务里面有多少个数字,比如说这里的10表示1个子任务里面有10个数字,你也可以理解成,以10个数组为单位分割1个子任务,重载构造方法用于初始化起始值和结束值。接下来编写compute的方法,我们先来写计算的代码,再来写分割任务的代码,用结束值减去起始值的结果去和临界值比大小,如果小于临界值,说明任务无法再分割,可以开始计算,定义一个int类型的局部变量sum,用于记录计算结果,使用for循环计算任务中的数字之和,接着返回计算结果,至此计算部分的代码写完了,再来编写分割任务部分的代码,首先取中间值,将任务从中间分割,取中间值的方法就是起始值与结束值的和除以二,这样将大任务分割成两个子任务。 其中一个子任务是计算从起始值到中间值之后,调用fork方法将子任务添加至线程池执行。另一个子任务是计算从中间值加一到结束值。为什么要加一?因为中间值已经归前一个子任务中,所以这里要往后移移一位,之后也是调用fork方法将子任务添加至线程池执行,最后调用子任务的join方法合并执行结果,至此compute方法编写完成。整个任务也编写完成。接下来执行该任务,首先将任务串联出来,并指定起始值和结束值,分别为1和100,然后创建focusjoin线程池,接着调用submit方法提交任务,接收方法返回值,再接着,调用get方法获取执行结果,get方法有异常抛出,使用try---catch将其捕获,紧接着输出任务,执行结果写上finally代码块。 在finally代码块中,要用shoudown方法关闭线程池,至此main方法编写完成,整个例子也编写完成,执行程序观察执行结果。从执行结果来看,程序输出5050,计算正确,大家可以试着将结束值写得更大一些,在和普通计算方法做比较,看谁计算的更快。最后总结一下本节内容。本杰介绍采用ffocusjoin框架的线程池,focusjoinPool它的作用及用法,这里就不再赘述了,在实际开发中我经常拿它来执行计算量大的任务,或者是数据量工作量很大的任务,这种将大任务拆分成一个个小任务的做法,它的工作效率远远超过一个线程执行大任务的效率。

 

标签:分割,16,ForkJoinPool,如何,任务,线程,起始值,编写,100
来源: https://www.cnblogs.com/cj8357475/p/16032790.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有