需求:使用Fork/Join计算1-10000的和,当一个任务的计算数量大于3000时拆分任务,数量小于3000时计算。
    image.png

    image.png
    image.png

    1. package com.itheima.demo05stream;
    2. import java.util.concurrent.ForkJoinPool;
    3. import java.util.concurrent.RecursiveTask;
    4. public class Demo08ForkJoin {
    5. public static void main(String[] args) {
    6. long start = System.currentTimeMillis();
    7. ForkJoinPool pool = new ForkJoinPool();
    8. SumRecursiveTask task = new SumRecursiveTask(1, 99999999999L);
    9. Long result = pool.invoke(task);
    10. System.out.println("result = " + result);
    11. long end = System.currentTimeMillis();
    12. System.out.println("消耗时间: " + (end - start));
    13. }
    14. }
    15. // 1.创建一个求和的任务
    16. // RecursiveTask: 一个任务
    17. class SumRecursiveTask extends RecursiveTask<Long> {
    18. // 是否要拆分的临界值
    19. private static final long THRESHOLD = 3000L;
    20. // 起始值
    21. private final long start;
    22. // 结束值
    23. private final long end;
    24. public SumRecursiveTask(long start, long end) {
    25. this.start = start;
    26. this.end = end;
    27. }
    28. @Override
    29. protected Long compute() {
    30. long length = end - start;
    31. if (length < THRESHOLD) {
    32. // 计算
    33. long sum = 0;
    34. for (long i = start; i <= end; i++) {
    35. sum += i;
    36. }
    37. return sum;
    38. } else {
    39. // 拆分
    40. long middle = (start + end) / 2;
    41. SumRecursiveTask left = new SumRecursiveTask(start, middle);
    42. left.fork();
    43. SumRecursiveTask right = new SumRecursiveTask(middle + 1, end);
    44. right.fork();
    45. return left.join() + right.join();
    46. }
    47. }
    48. }

    小结

    1. parallelStream是线程不安全的
    2. parallelStream适用的场景是CPU密集型的,只是做到别浪费CPU,假如本身电脑CPU的负载很大,那还到处用 并行流,那并不能起到作用
    3. I/O密集型 磁盘I/O、网络I/O都属于I/O操作,这部分操作是较少消耗CPU资源,一般并行流中不适用于I/O密集 型的操作,就比如使用并流行进行大批量的消息推送,涉及到了大量I/O,使用并行流反而慢了很多
    4. 在使用并行流的时候是无法保证元素的顺序的,也就是即使你用了同步集合也只能保证元素都正确但无法保证
    其中的顺序