ForkJoinPool分支/合并框架
ForkJoinPool分支/合并框架:就是在必要的情况下,将一个大任务,进行拆分(Fork)成若干个小任务(拆到不可拆时),再将一个个的小任务运算的结果进行join汇总。
- 采用“工作窃取”模式:
当执行新的任务的时候,它可以将其拆分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并放在自己的队列中。
- 相对于一般的线程池实现,fork/join框架的优势体现在对其中包含的任务的处理方式上。在一般的线程池中,如果一个线程正在执行的任务由于某些原因无法继续运行,那么该线程就会处于等待状态。而在fork/join框架实现中,如果某个子问题由于等待另一个子问题的完成而无法继续执行。那么处理该子问题的线程会主动寻找其他尚未运行的子问题来执行。这种方式减少了线程等待时间,提高性能。
public class TestForkJoinPool { public static void main(String[] args) { ForkJoinPool pool = new ForkJoinPool(); ForkJoinTask<Long> task = new ForkJoinSumCalculate(0,100000000); long sum = pool.invoke(task); System.out.println(sum); } } class ForkJoinSumCalculate extends RecursiveTask<Long>{ private long start; private long end; //临界值 private static final long THRESHOLD = 0; public ForkJoinSumCalculate(long start, long end) { this.start = start; this.end = end; } @Override protected Long compute() { long length = end - start; //小于临界值,则不再拆分 if (length<=THRESHOLD){ long sum = 0L; for (long i = start; i <= end; i++) { sum += i; } return sum; }else { //如果没有到临界值,则继续拆分任务 long middle = (start+end)/2; ForkJoinSumCalculate left = new ForkJoinSumCalculate(start,middle); left.fork();//进行拆分同时压入线程队列 ForkJoinSumCalculate right = new ForkJoinSumCalculate(middle+1,end); right.fork(); //合并小任务 return left.join() + right.join(); } } }