컬렉션에 parallelStream
을 호출하면 병렬 스트림(parallel stream)
이 생성된다.
병렬 스트림이란 각각의 스레드에서 처리할 수 있도록 스트림 요소를 여러 청크로 분할한 스트림이다. 따라서 병렬 스트림을 이용하면 모든 멀티코어 프로세서가 각각의 청크를 처리하도록 할당할 수 있다.
- EX) 숫자 n을 인수로 받아서 1부터 n까지의 모든 숫자의합계를 반환하는 메서드를 구현한다고 가정하자.
public long sequentialSum(long n) {
return Stream.iterate(1L, i->i+1)
.limit(n)
.reduce(0L, Long::sum);
}
// 반복문으로 구현
public long iterativeSum(long n) {
long result = 0;
for(long i = 1L; i <= n; i++) {
result += i;
}
return result;
}
여기서 n이 커진다면 이 연산을 병렬로 처리하는게 좋다. 결과 변수는 어떻게 동기화 할까?, 몇 개의 스레드를 사용할 까? 숫자는 어떻게 생성할까? 등의 걱정을 병렬 스트림을 이용하면 없앨 수 있다.
순차 스트림에 parallel()
메서드를 호출하면 기존의 함수형 리듀싱 연산(숫자 합계 계산)이 병렬로 처리된다. 반면에 sequential()
메서드를 호출하면
순차 스트림으로 바꿀 수 있다.
parallel()을 호출하면 내부적으로 병렬로 수행해야 함을 의미하는 불리언 플래그가 설정된다.
public long parallelSum(long n) {
return Stream.iterate(1L, i->i+1)
.limit(n)
.parallel()
.reduce(0L, Long::sum);
}
병렬 스트림을 이용하면 스트림이 여러 청크로 쪼개져서 연산을 수행한다.
병렬 스트림은 내부적으로 ForkJoinPool
을 사용한다