java fork-join框架应用和分析
? ? 这里,我们每一个小的task表示我们划分出来的一个子问题。当一个问题处理完毕后,他们的结果可以返回给原来调用他们的部分。如果我们用伪代码来描述一下divide and conquer策略的算法,则其基本的形式应该如下:
?
? ? 我们可以看到,他们共同的继承了AbstractExecutorService,在一定的程度上,他们是可以互相替换使用的。在图中我们还可以看到,ForkjoinPool使用到了RecursiveAction和RecursiveTask。他们两个中RecursiveAction应用于执行的任务不需要返回结果的场景,而RecursiveTask应用于需要返回执行结果的场景。这点类似于ThreadPoolExecutor使用Runnable和Callable的参数来分别表示不需要返回值和需要返回值的线程执行对象。
示例应用? ? OK,前面花了很多时间讨论了fork/join pool的特点,这里我们就来看几个具体的应用示例。
求最大值? ? 假定我们有一组数字,我们需要求里面的最大值。用我们传统的方法来求的话,其代码实现如下:
? ? 我们可以运行一下比较具体的执行结果。
总结? ? 从分治的算法思想到fork/join框架,这种并行性的的融入可以更加高效率的解决一大批的问题。和我们一些传统的多线程应用方式如ThreadPoolExecutor比起来,它有一些自己的特点。一个典型的地方就是work-stealing,它的一个优点是在传统的线程池应用里,我们分配的每个线程执行的任务并不能够保证他们执行时间或者任务量是同样的多,这样就可能出现有的线程完成的早,有的完成的晚。在这里,一个先完成的线程可以从其他正在执行任务的线程那里拿一些任务过来执行。我们可以说这是人家学习雷锋好榜样。这样发挥主观能动性的线程框架肯定办起事来就效率高了。
?
参考材料A Java Fork/Join framework
Programming concurrency on the jvm
http://www.javaworld.com/javaworld/jw-10-2011/111004-jtip-recursion-in-java-7.html?page=1
http://www.ibm.com/developerworks/cn/java/j-jtp11137.html?
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ForkJoinPool.html