使用多线程技术,让不同的任务在不同的线程中运行,可以提高CPU的利用率。然而只是仅仅通过任务来划分,粒度还是有点大。当任务中有些任务运行所占时间远远大于其它任务的时候,使用多线程并发所带来的效果并不明显。在这种情况下把耗时长的大任务划分为耗时短的小任务,可以有效地缓解并发的瓶颈,最终把小任务的结果合并获取完整的任务的结果。Fork/Join就可以很好地实现这种划分任务最后合并的思路(你可以把它当做并发版的分治)。
一、ForkJoinTask & ForkJoinPool
1. ForkJoinTask<V>
扩展自Future,它代表的是比任务更加轻量级,细粒度的并发单元。它本身是一个抽象类,这里提两个重要的抽象子类:RecursiveAction和RecursiveTask<V>,通过重写它们的compute方法可以定义任务,要注意的是前者的compute是不带返回值的,而后者的是有返回值的。
a. fork()方法允许ForkJoinTask任务异步执行,也允许一个新的ForkJoinTask从存在的ForkJoinTask中被启动。变种: invoke(), invokeAll()
b. 反过来, join()方法允许一个ForkJoinTask等待另一个ForkJoinTask执行完成。变种: get()
2. ForkJoinPool
继承自AbstractExecutorService,用于调度ForkJoinTask。