并行流parallelStream 替换默认线程池commonPool

  java8引入了stream流和并行流,极大的简化了多线程的操作,但是有一点要注意,parallelStream和completablefuture默认都是使用commonPool,参考源码:ForkJoinPool.commonPool();

项目所有流操作都是共享该池,当频繁的用于阻塞型任务(IO流:http请求等)时会导致整个项目卡顿,parallelStream只适用于cpu密集型的任务,但是我们可以将parallelStream使用自定义线程就可以避免这个问题。

1.使用自定义线程池作为并行流的线程池。

    public static void main(String[] args) {

        String[] firstRange = new String[100];
        String[] secondRange = new String[100];

     //线程池1 ForkJoinPool forkJoinPool
= new ForkJoinPool(3); forkJoinPool.submit(() -> { Stream.of(firstRange).parallel().forEach((number) -> { try { System.out.println("任务1的线程:" + Thread.currentThread().getName()); // do something slow Thread.sleep(5000); } catch (InterruptedException e) { } }); });      //线程池2  ForkJoinPool forkJoinPool2 = new ForkJoinPool(2); forkJoinPool2.submit(() -> { Stream.of(secondRange).parallel().forEach((number) -> { try { System.out.println("任务2的线程:" + Thread.currentThread().getName()); // do something slow Thread.sleep(5000); } catch (InterruptedException e) { } }); }); System.out.println("ok!!!!!!!!!!!!!!!!!!!"); try { Thread.sleep(1000000); } catch (Exception e) { } }

执行结果

可以看到第一个线程池使用了3个线程,第二个线程池使用了2个线程,线程数量可以自己指定,commonPool的默认线程数为cpu的核心数。

这样IO密集型的多线程操作就可以不占用commonPool线程池了。

2.当我们想对并行计算的结果进行处理时:

方式1:在ForkJoinPool池中处理,即submit方法内部处理(即上面的示例代码)。

方式2:当我们想把处理结果传递给主线程时,由于submit方法传递的是Runnable对象,没有返回值,那么我们可以用对象数组配合join方法处理,比如以下代码:

    说明:该方式和CompletableFuture区别是:

      CompletableFuture先提交异步线程执行任务,接下来可以做其他事情,需要得到结果的时候再通过CompletableFuture的返回参数得到。

      该方式:提交异步线程并立即等待结果(这里只是示例代码,可以做其他调整)

    public static void main(String[] args) {

        final Integer[] result = new Integer[1];
        String[] firstRange = new String[100000000];
        ForkJoinPool forkJoinPool = new ForkJoinPool(16);
        forkJoinPool.submit(() -> {

            Optional<Integer> reduce = Stream.of(firstRange).parallel().map((number) -> {
                return 1;
            }).reduce((integer, integer2) -> {
                //累加总次数
                return integer + integer2;
            });

            Integer integer = reduce.get();

            result[0] = integer;

            System.out.println("count:" + integer);
        }).join();

        System.out.println("并行计算结果:" + result[0]);

        System.out.println("ok!!!!!!!!!!!!!!!!!!!");


    }

执行结果

参考文章:https://blog.csdn.net/qq_32331073/article/details/85116698

原文地址:https://www.cnblogs.com/wulm/p/14547507.html