总结概括:

1.数据结构 归并排序 (也是后续排序 LRD)

2.多线程 ForkJoin框架 繁重任务的并行计算框架,map-reduce思想

计算代码

/****@author dongsheng*@date 2019/1/18 22:58*@Description:*@version 1.0.0*/public class ArrayMergerSortTask extends RecursiveAction {// implementation details follow:static final int THRESHOLD = 1000;final int[] array;final int lo, hi;ArrayMergerSortTask(int[] array, int lo, int hi) {this.array = array;this.lo = lo;this.hi = hi;}ArrayMergerSortTask(int[] array) {this(array, 0, array.length);}protected void compute() {if (hi - lo < THRESHOLD)      //小于1000,就排序sortSequentially(lo, hi);else {int mid = (lo + hi) >>> 1;     //大于1000,拆分invokeAll(new ArrayMergerSortTask(array, lo, mid),new ArrayMergerSortTask(array, mid, hi));merge(lo, mid, hi);}}void sortSequentially(int lo, int hi) {Arrays.sort(array, lo, hi);        //利用JDK自带的排序进行}void merge(int lo, int mid, int hi) {int[] buf = Arrays.copyOfRange(array, lo, mid);for (int i = 0, j = lo, k = mid; i < buf.length; j++)array[j] = (k == hi || buf[i] < array[k]) ? buf[i++] : array[k++];}public static void main(String[] args) throws Exception {// 这里以一个长度为2千的数组做示例int length = 2_000;int[] array = new int[length];// 填充数值Random random = new Random();for (int i = 0; i < length; i++) {array[i] = random.nextInt();System.out.println(array[i]);}// 利用forkjoinpool来完成多线程快速归并排序ArrayMergerSortTask stask = new ArrayMergerSortTask(array);ForkJoinPool pool = new ForkJoinPool();pool.submit(stask);// 等待任务完成stask.get();System.out.println("----------排序后的结果:");for (int d : array) {System.out.println(d);}}}

RecursiveAction

ForkJoinTask 的子类, 是 ForkJoinTask 的一个子类,它代表了一类最简单的 ForkJoinTask:不需要返回值,当子任务都执行完毕之后,不需要进行中间结果的组合。如果我们从 RecursiveAction 开始继承,那么我们只需要重载 protected void compute() 方法。

源码代码

/******* Written by Doug Lea with assistance from members of JCP JSR-166* Expert Group and released to the public domain, as explained at* http://creativecommons.org/publicdomain/zero/1.0/*/package java.util.concurrent;/*** A recursive resultless {@link ForkJoinTask}.  This class* establishes conventions to parameterize resultless actions as* {@code Void} {@code ForkJoinTask}s. Because {@code null} is the* only valid value of type {@code Void}, methods such as {@code join}* always return {@code null} upon completion.** <p><b>Sample Usages.</b> Here is a simple but complete ForkJoin* sort that sorts a given {@code long[]} array:**  <pre> {@code* static class SortTask extends RecursiveAction {*   final long[] array; final int lo, hi;*   SortTask(long[] array, int lo, int hi) {*     this.array = array; this.lo = lo; this.hi = hi;*   }*   SortTask(long[] array) { this(array, 0, array.length); }*   protected void compute() {*     if (hi - lo < THRESHOLD)*       sortSequentially(lo, hi);*     else {*       int mid = (lo + hi) >>> 1;*       invokeAll(new SortTask(array, lo, mid),*                 new SortTask(array, mid, hi));*       merge(lo, mid, hi);*     }*   }*   // implementation details follow:*   static final int THRESHOLD = 1000;*   void sortSequentially(int lo, int hi) {*     Arrays.sort(array, lo, hi);*   }*   void merge(int lo, int mid, int hi) {*     long[] buf = Arrays.copyOfRange(array, lo, mid);*     for (int i = 0, j = lo, k = mid; i < buf.length; j++)*       array[j] = (k == hi || buf[i] < array[k]) ?*         buf[i++] : array[k++];*   }* }}</pre>** You could then sort {@code anArray} by creating {@code new* SortTask(anArray)} and invoking it in a ForkJoinPool.  As a more* concrete simple example, the following task increments each element* of an array:*  <pre> {@code* class IncrementTask extends RecursiveAction {*   final long[] array; final int lo, hi;*   IncrementTask(long[] array, int lo, int hi) {*     this.array = array; this.lo = lo; this.hi = hi;*   }*   protected void compute() {*     if (hi - lo < THRESHOLD) {*       for (int i = lo; i < hi; ++i)*         array[i]++;*     }*     else {*       int mid = (lo + hi) >>> 1;*       invokeAll(new IncrementTask(array, lo, mid),*                 new IncrementTask(array, mid, hi));*     }*   }* }}</pre>** <p>The following example illustrates some refinements and idioms* that may lead to better performance: RecursiveActions need not be* fully recursive, so long as they maintain the basic* divide-and-conquer approach. Here is a class that sums the squares* of each element of a double array, by subdividing out only the* right-hand-sides of repeated divisions by two, and keeping track of* them with a chain of {@code next} references. It uses a dynamic* threshold based on method {@code getSurplusQueuedTaskCount}, but* counterbalances potential excess partitioning by directly* performing leaf actions on unstolen tasks rather than further* subdividing.**  <pre> {@code* double sumOfSquares(ForkJoinPool pool, double[] array) {*   int n = array.length;*   Applyer a = new Applyer(array, 0, n, null);*   pool.invoke(a);*   return a.result;* }** class Applyer extends RecursiveAction {*   final double[] array;*   final int lo, hi;*   double result;*   Applyer next; // keeps track of right-hand-side tasks*   Applyer(double[] array, int lo, int hi, Applyer next) {*     this.array = array; this.lo = lo; this.hi = hi;*     this.next = next;*   }**   double atLeaf(int l, int h) {*     double sum = 0;*     for (int i = l; i < h; ++i) // perform leftmost base step*       sum += array[i] * array[i];*     return sum;*   }**   protected void compute() {*     int l = lo;*     int h = hi;*     Applyer right = null;*     while (h - l > 1 && getSurplusQueuedTaskCount() <= 3) {*       int mid = (l + h) >>> 1;*       right = new Applyer(array, mid, h, right);*       right.fork();*       h = mid;*     }*     double sum = atLeaf(l, h);*     while (right != null) {*       if (right.tryUnfork()) // directly calculate if not stolen*         sum += right.atLeaf(right.lo, right.hi);*       else {*         right.join();*         sum += right.result;*       }*       right = right.next;*     }*     result = sum;*   }* }}</pre>** @since 1.7* @author Doug Lea*/public abstract class RecursiveAction extends ForkJoinTask<Void> {private static final long serialVersionUID = 5232453952276485070L;/*** The main computation performed by this task.*/protected abstract void compute();/*** Always returns {@code null}.** @return {@code null} always*/public final Void getRawResult() { return null; }/*** Requires null completion value.*/protected final void setRawResult(Void mustBeNull) { }/*** Implements execution conventions for RecursiveActions.*/protected final boolean exec() {compute();return true;}}

invoke 数组_如何对一个亿的数组进行快速排序相关推荐

  1. java如何定义一个变长数组_如何自定义一个长度可变数组

    摘要:本文主要写了如何自定义一个长度可变数组 数组是在程序设计中,为了处理方便,把具有相同类型的若干元素按无序的形式组织起来的一种形式 在定义之初,数组的长度就被定义 新建数组有很多方式 下面两个都可 ...

  2. int java 声明_怎样用java定义一个int数组 C++ 怎么声明一个整型数组?

    导航:网站首页 > 怎样用java定义一个int数组 C++ 怎么声明一个整型数组? 怎样用java定义一个int数组 C++ 怎么声明一个整型数组? 相关问题: 匿名网友: int[] anA ...

  3. java数组及Arrays创建一个int 类型数组 数组元素由键盘录入,每次打印插入排序的结果(数组扩容,数组排序,键盘录入)

    @author silence丶你的名字 java数组及Arrays创建一个int 类型数组 数组元素由键盘录入,每次打印插入排序的结果 初始数组元素1 for死循环 获取用户录入的数据,如果为952 ...

  4. 《c primer pius》第十章第6题,编写一个程序,初始化一个二维double数组,并利用练习2中的任一函数来把这个数组复制到另一个二维数组(因为二维数组是数组的数组,所以可以使用处理一维数组的

    <c primer pius>第十章第6题,编写一个程序,初始化一个二维double数组,并利用练习2中的任一函数来把这个数组复制到另一个二维数组(因为二维数组是数组的数组,所以可以使用处 ...

  5. c语言把一个数组赋值给另一个数组_如何把一个固定数组的值传递给另外一个数组...

    大家好,今日我们继续讲解VBA数组与字典解决方案,今日讲解的是第34讲:数组的传递.在应用数组的时候,我们往往需要要把数组的值由一个数组传递给另外一个数组,就如同变量的传递一样: A=B '把B值赋给 ...

  6. scala 字符串转换数组_如何在Scala中将字节数组转换为字符串?

    scala 字符串转换数组 Byte Array in Scala is an array of elements of a byte type. String in Scala is a colle ...

  7. javascript字典中添加数组_如何在JavaScript中使用数组方法:Mutator方法

    JavaScript中的数组由元素列表组成.JavaScript有许多有用的内置方法来处理数组.修改原始数组的方法称为mutator方法,返回新值或表示的方法称为accessor方法.在本教程中,我们 ...

  8. doctrine find的对象转换成数组_「ES6基础」Array数组的新方法(上)

    在日常工作中我们经常会与数组打交道,因此需要熟练掌握数组操作的相关方法,ES6中关于数组的操作,又给我们带来了哪些惊喜呢,Array数组操作又添加了哪些新方法? 本篇文章将从以下几个方面进行介绍: A ...

  9. es6一维数组转二维数组_技术图文:Numpy 一维数组 VS. Pandas Series

    背景 Numpy 提供的最重要的数据结构是 ndarray,它是 Python 中 list 的扩展. Pandas 提供了两种非常重要的数据结构 Series和DataFrame. Numpy 中的 ...

最新文章

  1. 2017-02-20 注册.Net Framework4.0
  2. js获取网页高度(详细整理)
  3. golang nil slice 和 empty slic 的区别 空切片
  4. golang中的goredis
  5. Linux┊理解devfs、sysfs、udev、tmpfs
  6. VScode设置中文
  7. mysql读写分离有用吗_MySQL的使用中实现读写分离的教程
  8. mybatis批量更新
  9. SummerBoot,将SpringBoot的先进理念与C#的简洁优雅合二为一
  10. Java和Android中的注解
  11. VirtualAllocEx 跨进程读写数据 代码注入
  12. DOS批处理高级教程精选(二)
  13. KB-QA:如何对问题进行信息抽取?
  14. UVA-1602 Lattice Animals 搜索问题(打表+set)
  15. 区块链技术与微服务架构之间有什么关系?
  16. Javascript特效:普通倒计时
  17. 你真的懂Linux吗?Linux运维快速入门学习方法
  18. Nginx - 正向代理与反向代理的概念
  19. excel根据html生成表头c,excel表头的制作 怎样在Excel里面制作表头?
  20. 在python中安装包出现Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))

热门文章

  1. 移动广告聚合管理-KeyMob|移动广告聚合平台|
  2. Unicode和UTF-8的关系
  3. 让Flash背景透明兼容Firefox、IE 6和IE 7的代码
  4. 微软MCITP系列课程(四)磁盘系统管理
  5. 网管员破网“利剑”——统一网络拓扑发现
  6. 开发者和矿工合二为一将是比特币世界的灾难
  7. 甲骨文 93 亿美元现金收购云计算商 NetSuite
  8. string之substring的用法
  9. SAP+ 差旅报销集成方案的实现
  10. 2015年11月 广州深圳 MVP 线下活动