10. Stream流 --- 串行流/并行流/普通for循环对比
1. 串行Stream流
之前的一篇文章都是串行的Stream流,也就是再一个线程上面执行。
串行流的效率低。
@Test
@DisplayName("串行流单线程的验证")
public void test24() {
long count = Stream.of(5, 6, 8, 3, 4, 0).filter(s -> {
System.out.println(Thread.currentThread() + " " + s);
return s > 3;
}).count();
System.out.println(count);
}
Result:
Thread[main,5,main] 5
Thread[main,5,main] 6
Thread[main,5,main] 8
Thread[main,5,main] 3
Thread[main,5,main] 4
Thread[main,5,main] 0
4
2. 并行流
paralleStream其实就是一个并行执行的流,它通过默认的ForkJoinPool,可以提高多线程任务的速度。
获取并行流的两种方式
- 1.通过List接口中的parallelStream方法来获取
-
- 通过已有的串行流转换为并行流
方式a:通过List接口中的parallelStream方法来获取
@Test
@DisplayName("通过List接口中的parallelStream方法来获取")
public void test25() {
ArrayList<Integer> list = new ArrayList<>();
// 通过List接口直接获取并行流
Stream<Integer> integerStream = list.parallelStream();
}
方式b:通过已有的串行流转换为并行流
@Test
@DisplayName("通过已有的串行流转换为并行流")
public void test26() {
// 通过已有的串行流转换为并行流
Stream<Integer> parallel = Stream.of(1, 2, 3).parallel();
}
并行(并发)流操作
将流转换为并发流,Stream处理的时候就会通过多线程处理
@Test
@DisplayName("【案例】:并行流操作")
public void test27() {
long count = Stream.of(1, 4, 6, 7, 3)
.parallel()
.filter(s -> {
System.out.println(Thread.currentThread() + "s = " + s);
return s > 2;
}).count();
System.out.println("count = " + count);
}
Thread[ForkJoinPool.commonPool-worker-4,5,main]s = 7
Thread[ForkJoinPool.commonPool-worker-3,5,main]s = 1
Thread[ForkJoinPool.commonPool-worker-2,5,main]s = 3
Thread[ForkJoinPool.commonPool-worker-1,5,main]s = 4
Thread[main,5,main]s = 6
count = 4
并行流和串行流对比
通过for循环,串行Stream流,并行流来对1000000000个数字求和,来看消耗时间。
1. 普通for循环
// 10亿
private static long times = 1000000000;
private long start;
@Before
public void before(){
start = System.currentTimeMillis();
}
@org.junit.Test
@DisplayName("普通for循环")
public void test28() {
long res = 0;
for (int i = 0; i < times ; i++) {
res +=i;
}
System.out.println("res = " + res);
}
@After
public void end() {
long end = System.currentTimeMillis();
System.out.println("消耗时间" + (end - start));
}
res = 499999999500000000
消耗时间467
2. 串行流
@org.junit.Test
@DisplayName("串行流")
public void test29() {
long reduce = LongStream.rangeClosed(0, times).reduce(0, Long::sum);
System.out.println(reduce);
}
500000000500000000
消耗时间607
3. 并行流
@org.junit.Test
@DisplayName("并行流")
public void test30() {
long reduce = LongStream.rangeClosed(0, times).parallel().reduce(0, Long::sum);
System.out.println(reduce);
}
500000000500000000
消耗时间225
通过上面的普通for循环
、串行流
、并行流
可以发现,再10亿条数据进行累加求和的时候,并行效率最高。
但是要合理选择,数据量小的时候,并行流的速度并不一定快。
Stream并行流处理的过程会分而治之,也就是将一个大的任务切分成了多个小任务,这表示每个任务都是一个线程操作。