parallelStream并行流

文章目录

  • 1. parallelStream 是并行的
  • 2. Fork/Join

1. parallelStream 是并行的

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
numbers.parallelStream().forEach(num->System.out.print(num + " "));
System.out.println();
System.out.println("----------------");

numbers.parallelStream() .forEach(num->System.out.println(Thread.currentThread().getName()+">>"+num));

打印结果:

6 5 3 2 7 9 4 1 8 
----------------
main>>6
ForkJoinPool.commonPool-worker-1>>7
ForkJoinPool.commonPool-worker-4>>1
ForkJoinPool.commonPool-worker-2>>2
ForkJoinPool.commonPool-worker-3>>5
ForkJoinPool.commonPool-worker-6>>3
ForkJoinPool.commonPool-worker-7>>8
ForkJoinPool.commonPool-worker-1>>9
ForkJoinPool.commonPool-worker-5>>4

结论:

从上面的打印结果可以看出,它的输出是并发的
其底层使用Fork/Join框架实现
parallelStream是利用多线程进行的,这可以很大程度简化我们使用并发操作。
我们可以通过虚拟机启动参数
-Djava.util.concurrent.ForkJoinPool.common.parallelism=20
来设置worker的数量。

在虚拟机启动时,我们指定了worker线程的数量,整个程序的生命周期都将使用这些工作线程;
这必然存在任务生产和消费的问题,如果某个生产者生产了许多重量级的任务(耗时很长),
那么其他任务毫无疑问将会没有工作线程可用;更可怕的事情是这些工作线程正在进行IO阻塞。

并行流有线程安全问题,慎用

2. Fork/Join

Fork/Join 它可以将一个大的任务拆分成多个子任务进行并行处理,最后将子任务结果合并成最后的计算结果,并进行输出。

Fork/Join 框架要完成两件事情:
Fork:把一个复杂任务进行分拆,大事化小
Join:把分拆任务的结果进行合并

任务分割:
首先 Fork/Join 框架需要把大的任务分割成足够小的子任务,如果子任务比较大的话还要对子任务进行继续分割。
执行任务并合并结果:分割的子任务分别放到双端队列里,然后几个启动线程分别从双端队列里获取任务执行。
子任务执行完的结果都放在另外一个队列里,启动一个线程从队列里取数据,然后合并这些数据。

你可能感兴趣的:(Java基础知识,java)