JDK8 | 串行流 Stream 与并行流 parallelStream
一、串行 Stream 流
1.获取串行流的两种方式:
- 所有的 Collection 集合都可以通过 stream 默认方法获取流:
list.stream();
- Stream 接口的静态方法 of 可以获取数组对应的流:
Stream.of(6,1,5,4,3);
// 集合获取流
// Collection接口中的方法: default Stream<E> stream() 获取流
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
Set<String> set = new HashSet<>();
Stream<String> stream2 = set.stream();
Vector<String> vector = new Vector<>();
Stream<String> stream3 = vector.stream();
// Map获取流
Map<String, String> map = new HashMap<>();
Stream<String> keyStream = map.keySet().stream();
Stream<String> valueStream = map.values().stream();
Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();
2.Stream常用方法,其他方法大家自行查阅官方API文档
3.Stream注意事项(重要)
- Stream只能操作一次
- Stream方法返回的是新的流
- Stream不调用终结方法,中间的操作不会执行
二、并行 parallelStream 流
1.获取并行流的两种方式:
- 直接获取并行的流:
- 将串行流转成并行流:
// 直接获取并行的流
ArrayList<Integer> list = new ArrayList<>();
Stream<Integer> stream = list.parallelStream();
// 将串行流转成并行流
ArrayList<Integer> list2 = new ArrayList<>();
Stream<Integer> stream = list2.stream().parallel();
2.并行流的效率是要比串行流要高,底层使用Fork/Join
框架进行处理,具体自行百度
测试效率
public class Demo {
private static long times = 50000000000L;
private long start;
@Before
public void init() {
start = System.currentTimeMillis();
}
@After
public void destory() {
long end = System.currentTimeMillis();
System.out.println("消耗时间: " + (end - start));
}
// 测试效率,parallelStream 122
@Test
public void parallelStream() {
System.out.println("serialStream");
LongStream.rangeClosed(0, times).parallel().reduce(0, Long::sum);
}
// 测试效率,普通Stream 354
@Test
public void serialStream() {
System.out.println("serialStream");
LongStream.rangeClosed(0, times).reduce(0, Long::sum);
}
}
3.解决并行流的线程安全问题:多线程下,使用并行流会有线程安全的问题
根据需要进行不同的处理:
- 使用同步代码块
synchronized
(比如使用forEach循环处理时) - 使用线程安全的集合
Vector、Collections.synchronizedList(list)
- 调用Stream流的
collect/toArray
方法
4.注意事项
- parallelStream是线程不安全的
- parallelStream适用的场景是CPU密集型的,只是做到别浪费CPU,假如本身电脑CPU的负载很大,那还到处用并行流,那并不能起到作用
- I/O密集型 磁盘I/O、网络I/O都属于I/O操作,这部分操作是较少消耗CPU资源,一般并行流中不适用于I/O密集型的操作,就比如使用并流行进行大批量的消息推送,涉及到了大量I/O,使用并行流反而慢了很多
- 在使用并行流的时候是无法保证元素的顺序的,也就是即使你用了同步集合也只能保证元素都正确但无法保证其中的顺序
欢迎关注公众号:慌途L
后面会慢慢将文章迁移至公众号,也是方便在没有电脑的情况下可以进行翻阅,更新的话会两边同时更新,大家不用担心!