制作自己网站有什么软件,做的比较漂亮的中国网站,wordpress get_option,樟树市建设局网站在JAVA7之前#xff0c;并行处理数据非常麻烦。第一#xff0c;你得明确把包含数据的数据结构分成若干份。第二#xff0c;你要将每个子部分分配给一个独立的线程。第三#xff0c;你要在恰当的时候对它们进行同步避免不希望的竞争条件#xff0c;等待所有线程完成#x… 在JAVA7之前并行处理数据非常麻烦。第一你得明确把包含数据的数据结构分成若干份。第二你要将每个子部分分配给一个独立的线程。第三你要在恰当的时候对它们进行同步避免不希望的竞争条件等待所有线程完成最后把这些部分结果合并起来。在Java 7引入了分支/合并框架让这些操作更稳定、更不容易出错。 分支/合并框架的目的是以递归的方式将可以并行的任务拆分为更小的任务然后将每个子任务的结果合并起来生成整体结果。要把子任务提交到ForkJoinPool必须创建RecursiveTaskR的子类。需要实现它唯一的抽象方法 protected abstract R compute(); 在这个方法中定义了将任务拆分成子任务的逻辑以及无法拆分时生成单个子任务结果的逻辑。 计算1到10000000的和 /*** Desc:Fork/Join框架的目的是以递归方式将可以并行的任务拆分为更小的任务然后将每个子任务的结果合并起来生成一个整体结果。* 要把任务提交到ForkJoinPool必须创建RecursiveTaskT 的一个子类* * author wei.zw* since 2016年7月6日 下午9:27:56* version v 0.1*/
public class ForkJoinSumCalculator extends RecursiveTaskLong {/** */private static final long serialVersionUID -8013303660374621470L;private final long[] numbers;private final int start;private final int end;private static final long THRESHOLD 1000;/*** param numbers* param start* param end*/public ForkJoinSumCalculator(long[] numbers, int start, int end) {super();this.numbers numbers;this.start start;this.end end;}/*** param numbers*/public ForkJoinSumCalculator(long[] numbers) {super();this.numbers numbers;this.start 0;this.end numbers.length;}/*** see java.util.concurrent.RecursiveTask#compute()*/Overrideprotected Long compute() {int length end - start;if (length THRESHOLD) {return computeSequentially();}ForkJoinSumCalculator leftTask new ForkJoinSumCalculator(numbers, start, start length / 2);leftTask.fork();ForkJoinSumCalculator rightTask new ForkJoinSumCalculator(numbers, start length / 2, end);rightTask.fork();Long rightResult 0L;try {rightResult rightTask.get();} catch (Exception e) {}Long leftResult leftTask.join();return leftResult rightResult;}/*** * return* author wei.zw*/private Long computeSequentially() {long sum 0;for (int i start; i end; i) {sum numbers[i];}return sum;}public static void main(String[] args) {long[] numbers LongStream.rangeClosed(1, 10000000).toArray();long start System.currentTimeMillis();System.out.println(new ForkJoinPool().invoke(new ForkJoinSumCalculator(numbers)) 耗时 (System.currentTimeMillis() - start));}}结果是50000005000000 耗时37 优化后的 /*** see java.util.concurrent.RecursiveTask#compute()*/Overrideprotected Long compute() {int length end - start;if (length THRESHOLD) {return computeSequentially();}ForkJoinSumCalculator leftTask new ForkJoinSumCalculator(numbers, start, start length / 2);leftTask.fork();ForkJoinSumCalculator rightTask new ForkJoinSumCalculator(numbers, start length / 2, end);Long rightResult rightTask.compute();Long leftResult leftTask.join();return leftResult rightResult;}计算结果是50000005000000 耗时25 使用Fork/Join框架的最佳做法 对一个任务调用join方法会阻塞调用方直到该任务作出结果。因此又必须要在两个子任务的计算都开始之后再调用它。不应该在RecursiveTask内部使用ForkJoinPool的invoke方法应该直接调用compute或者fork方法对子任务调用fork方法可以将这个子任务排进ForkJoinPool。同时对左右两边的子任务都调用似乎很自然但是这样做的效率比直接对其中一个调用compute方法低。这样做可以为其中一个子任务重用同一线程从而避免在线程池中多分配一个任务造成的开销。看完了基本示例在分析一下源码首先看一下RecursiveTask通过名称可以知道这是一个递归Task.源码很简单 public abstract class RecursiveTaskV extends ForkJoinTaskV {private static final long serialVersionUID 5232453952276485270L;//计算结果V result;//抽象的计算方法protected abstract V compute();//获取计算结果public final V getRawResult() {return result;}//设置计算结果protected final void setRawResult(V value) {result value;}//执行计算protected final boolean exec() {result compute();return true;}}RecursiveTask源码看完以后继续分析ForkJoinTask 转载于:https://www.cnblogs.com/wei-zw/p/8797732.html