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