• 并发编程- 线程池ForkJoinPool工作原理分析(实践)


     数据结构加油站:

    Comparison Sorting Visualization

    并发设计模式

    单线程归并排序

    1. public class MergeSort {
    2. private final int[] arrayToSort; //要排序的数组
    3. private final int threshold; //拆分的阈值,低于此阈值就不再进行拆分
    4. public MergeSort(final int[] arrayToSort, final int threshold) {
    5. this.arrayToSort = arrayToSort;
    6. this.threshold = threshold;
    7. }
    8. /**
    9. * 排序
    10. * @return
    11. */
    12. public int[] mergeSort() {
    13. return mergeSort(arrayToSort, threshold);
    14. }
    15. public static int[] mergeSort(final int[] arrayToSort, int threshold) {
    16. //拆分后的数组长度小于阈值,直接进行排序
    17. if (arrayToSort.length < threshold) {
    18. //调用jdk提供的排序方法
    19. Arrays.sort(arrayToSort);
    20. return arrayToSort;
    21. }
    22. int midpoint = arrayToSort.length / 2;
    23. //对数组进行拆分
    24. int[] leftArray = Arrays.copyOfRange(arrayToSort, 0, midpoint);
    25. int[] rightArray = Arrays.copyOfRange(arrayToSort, midpoint, arrayToSort.length);
    26. //递归调用
    27. leftArray = mergeSort(leftArray, threshold);
    28. rightArray = mergeSort(rightArray, threshold);
    29. //合并排序结果
    30. return merge(leftArray, rightArray);
    31. }
    32. public static int[] merge(final int[] leftArray, final int[] rightArray) {
    33. //定义用于合并结果的数组
    34. int[] mergedArray = new int[leftArray.length + rightArray.length];
    35. int mergedArrayPos = 0;
    36. // 利用双指针进行两个数的比较
    37. int leftArrayPos = 0;
    38. int rightArrayPos = 0;
    39. while (leftArrayPos < leftArray.length && rightArrayPos < rightArray.length) {
    40. if (leftArray[leftArrayPos] <= rightArray[rightArrayPos]) {
    41. mergedArray[mergedArrayPos] = leftArray[leftArrayPos];
    42. leftArrayPos++;
    43. } else {
    44. mergedArray[mergedArrayPos] = rightArray[rightArrayPos];
    45. rightArrayPos++;
    46. }
    47. mergedArrayPos++;
    48. }
    49. while (leftArrayPos < leftArray.length) {
    50. mergedArray[mergedArrayPos] = leftArray[leftArrayPos];
    51. leftArrayPos++;
    52. mergedArrayPos++;
    53. }
    54. while (rightArrayPos < rightArray.length) {
    55. mergedArray[mergedArrayPos] = rightArray[rightArrayPos];
    56. rightArrayPos++;
    57. mergedArrayPos++;
    58. }
    59. return mergedArray;
    60. }

    forkjoin排序

    1. /**
    2. * 利用fork-join实现数组排序
    3. */
    4. public class MergeSortTask extends RecursiveAction {
    5. private final int threshold; //拆分的阈值,低于此阈值就不再进行拆分
    6. private int[] arrayToSort; //要排序的数组
    7. public MergeSortTask(final int[] arrayToSort, final int threshold) {
    8. this.arrayToSort = arrayToSort;
    9. this.threshold = threshold;
    10. }
    11. @Override
    12. protected void compute() {
    13. //拆分后的数组长度小于阈值,直接进行排序
    14. if (arrayToSort.length <= threshold) {
    15. // 调用jdk提供的排序方法
    16. Arrays.sort(arrayToSort);
    17. return;
    18. }
    19. // 对数组进行拆分
    20. int midpoint = arrayToSort.length / 2;
    21. int[] leftArray = Arrays.copyOfRange(arrayToSort, 0, midpoint);
    22. int[] rightArray = Arrays.copyOfRange(arrayToSort, midpoint, arrayToSort.length);
    23. MergeSortTask leftTask = new MergeSortTask(leftArray, threshold);
    24. MergeSortTask rightTask = new MergeSortTask(rightArray, threshold);
    25. //调用任务,阻塞当前线程,直到所有子任务执行完成
    26. invokeAll(leftTask,rightTask);
    27. //提交任务
    28. // leftTask.fork();
    29. // rightTask.fork();
    30. // //合并结果
    31. // leftTask.join();
    32. // rightTask.join();
    33. // 合并排序结果
    34. arrayToSort = MergeSort.merge(leftTask.getSortedArray(), rightTask.getSortedArray());
    35. }
    36. public int[] getSortedArray() {
    37. return arrayToSort;
    38. }

    随机生成一个数组的工具类

    1. public class Utils {
    2. /**
    3. * 随机生成数组
    4. * @param size 数组的大小
    5. * @return
    6. */
    7. public static int[] buildRandomIntArray(final int size) {
    8. int[] arrayToCalculateSumOf = new int[size];
    9. Random generator = new Random();
    10. for (int i = 0; i < arrayToCalculateSumOf.length; i++) {
    11. arrayToCalculateSumOf[i] = generator.nextInt(100000000);
    12. }
    13. return arrayToCalculateSumOf;
    14. }
    15. }

    单线程归并排序 & forkjoin排序  对比

    1. public class ArrayToSortMain {
    2. public static void main(String[] args) {
    3. //生成测试数组 用于归并排序
    4. int[] arrayToSortByMergeSort = Utils.buildRandomIntArray(20000000);
    5. //生成测试数组 用于forkjoin排序
    6. int[] arrayToSortByForkJoin = Arrays.copyOf(arrayToSortByMergeSort, arrayToSortByMergeSort.length);
    7. //获取处理器数量
    8. int processors = Runtime.getRuntime().availableProcessors();
    9. MergeSort mergeSort = new MergeSort(arrayToSortByMergeSort, processors);
    10. long startTime = System.nanoTime();
    11. // 归并排序
    12. mergeSort.mergeSort();
    13. long duration = System.nanoTime()-startTime;
    14. System.out.println("单线程归并排序时间: "+(duration/(1000f*1000f))+"毫秒");
    15. //利用forkjoin排序
    16. MergeSortTask mergeSortTask = new MergeSortTask(arrayToSortByForkJoin, processors);
    17. //构建forkjoin线程池
    18. ForkJoinPool forkJoinPool = new ForkJoinPool(processors);
    19. startTime = System.nanoTime();
    20. //执行排序任务
    21. forkJoinPool.invoke(mergeSortTask);
    22. duration = System.nanoTime()-startTime;
    23. System.out.println("forkjoin排序时间: "+(duration/(1000f*1000f))+"毫秒");
    24. }
    25. }

    执行结果

  • 相关阅读:
    Windows C盘清理
    PyTorch学习笔记(四)
    CAPL语言编译的那些事
    MIPI 打怪升级之D-PHY篇
    腾讯云字幕接口api整理笔记
    RAC+ADG switch over 演练时TNS配置
    Mozilla 项目
    好用的源代码加密软件有哪些?5款源代码防泄密软件推荐
    左支座零件的机械加工工艺规程及工艺装备设计【计算机辅助设计与制造CAD】
    硅谷甄选运营平台-笔记
  • 原文地址:https://blog.csdn.net/weixin_43874650/article/details/134067280