package com.cf.example.java.java8.stream;

import java.util.ArrayList;
import java.util.List;

/**
 * 流元素并发使用
 *
 * @author ylfcf
 * @date 20-7-4 上午10:18
 */
public class ParallelStreamUse {
    public static void main(String[] args) {
        List<String> stringList = new ArrayList() {{
            add("1");
            add("2");
            add("3");
            add("4");
            add("5");
        }};
        stringList.parallelStream().forEach(string -> {
            System.out.println(Thread.currentThread().getName() + "\t" + string);
        });
    }
}

2、并发(线程池)设置

parallelStream并行,底层实现采用ForkJoin,线程池大小默认为:cpu核心数

获取cpu核心数代码:

Runtime.getRuntime().availableProcessors();

手动设置ForkJoin线程池大小

// 线程池大小配置为20
String FORK_JOIN_POOL_PARALLELISM = "java.util.concurrent.ForkJoinPool.common.parallelism";
System.setProperty(FORK_JOIN_POOL_PARALLELISM, "20");

PS:在JDK源码中,ForkJoinPool.java下makeCommonPool()方法中可找到该属性配置

使用parallelStream时需要注意的一点是,多个parallelStream之间默认使用的是同一个线程池,所以IO操作尽量不要放进parallelStream中,否则会阻塞其他parallelStream。

为什么parallelStream默认的并发线程数要比CPU处理器的数量少1个?文章的开始已经提过了。因为最优的策略是每个CPU处理器分配一个线程,然而主线程也算一个线程,所以要占一个名额。

parallelStream应该会阻塞当前线程,处理完成后才会进行后续逻辑处理

在使用并行流的时候是无法保证元素的顺序的,也就是即使你用了同步集合也只能保证元素都正确但无法保证其中的顺序