자바

병렬 처리를 위해 코드에서 포크조인 프레임워크를 직접 사용할 수는 있지만, 병렬 스트림을 이용할 경우에는 백그라운드에서 포크조인 프레임워크가 사용되기 때문에 개발자는 매우 쉽게 병렬 처리를 할 수 있다. 병렬 스트림은 다음 두 가기 메소드로 얻을 수 있다.

인터페이스 리턴 타입 메소드(매개 변수)
java.util.Collection Stream parallelStream()

java.util.Stream.Stream

java.util.Stream.IntStream

java.util.Stream.LongStream

java.util.Stream.DoubleStream

Stream

IntStream

LongStream

DoubleStream

parallel()

parallelStream() 메소드는 컬렉션으로부터 병렬 스트림을 바로 리턴한다. parallel() 메소드는 순차 처리 스트림을 병렬 처리 스트림으로 변환해서 리턴한다. 어떤 방법으로 병렬 스트림을 얻더라도 이후 요소 처리 과정은 병렬 처리 된다. 내부적으로 전체 요소를 서브 요소들로 나누고, 이 서브 요소들을 개별 스레드가 처리한다. 서브 처리 결과가 나오면 결합해서 마지막으로 최종 처리 결과를 리턴한다. 내부적인 동작을 확인하려면 16.11.2 사용자 정의 컨테이너에 수집하기에서 살펴본 예제를 병렬 스트림으로 수정해서 실행해보면 된다. 먼저 수정 전의 코드를 보자.

 

MaleStudent maleStudent = totalList.stream()

.filter(s ->s.getSex() == Student.Sex.MALE)

.collect(MaleStudent :: new, MaleStudent :: accumulate, MaleStudent :: combine);

 

전체 학생 목록에서 stream() 메소드로 순차 처리 스트림을 얻었기 때문에 MaleStudent 객체는 하나만 생성되고, 남학생을 MaleStudent 에 수집하기 위해 accumulate() 가 호출된다.

combine() 메소드는 전혀 호출되지 않았는데, 그 이유는 순차 처리 스트림이므로 결합할 서브 작업이 없기 때문이다.

이 코드를 병렬 처리 스트림으로 변경하면 다음과 같다.

MaleStudent maleStudent =totalList.parallelStream()

.filter(s ->s.getSex() ==Student.Sex.MALE)

.collect(MaleStudent :: new, MaleStudent :: accumulate, MaleStudent :: combine);

단순히 stream() 메소드 호출이 parallelStream() 메소드 호출로 변경되었지만 내부 동작은 다음과 같은 순서로 전혀 다르게 진행된다.

1. 쿼드 코어 CPU 에서 실행된다면 전체 요소는 4개의 서브 요소로 나눠지고, 4개의 스레드가 병렬 처리한다. 각 스레드는 서브 요소를 수집해야 하므로 4개의 MaleStudent 객체를 생성하기 위해 collect() 의 첫 번째 메소드 참조인 MaleStudent :: new 를 4번 실행시킨다.

2. 각 스레드는 MaleStudent 객체에 남학생 요소를 수집하기 위해 두 번째 메소드 참조인 MaleStudent :: accumulate 를 매번 실행시킨다.

3. 수집이 완료된 4개의 MaleStudent는 3번의 결합으로 최종  MaleStudent 가 만들어질 수 있으므로 세 번째 메소드 참조인 MaleStudent :: combine 가 3번 실행된다.

 

 

 

 

 

 

about author

PHRASE

Level 60  머나먼나라

인생은 그것을 느끼는 인간에게 있어서는 비극이고, 생각하는 인간에게 희극이다. -라 브뤼에르

댓글 ( 4)

댓글 남기기

작성

자바 목록    more