[이펙티브자바] 48강. 스트림 병렬화는 주의해서 적용하라

serious_yeon·2023년 3월 12일
0

책읽자

목록 보기
1/3
목차
자바의 동시성 프로그래밍이란
스트림이란
스트림 병렬처리란

자바의 동시성 프로그래밍

동시성 프로그래밍이란, 싱글 프로세서에서 멀티 스레드를 동작시키는 것이다. 스레드를 바꿀 때는 관련 정보를 읽어오느라 시간과 비용이 발생한다(Context Switching). 이걸 최소화하는 게 중요하다.

자바는 동시성 프로그래밍 관련해서 여러 기능을 지원한다.

- 스레드, 동기화, wait/notify
- 포크 조인 패키지
- 스트림 파이프라인의 parallel

동시성 프로그래밍을 적용한다고 해서 무조건 성능이 좋아지는 것은 아니다. 성능이 좋아질 수 있는 경우를 파악해야 하며, 동시성 프로그래밍을 적용한 후에도 성능 테스트를 수행해서 검사해야 한다.

스트림이란

스트림 예시를 보면 감이 온다.

Stream.iterate(1L ,i -> i + 1)
      .limit(n)
      .parallel()
      .reduce(0L, Long::sum);
  • for문으로 접근하던 것을 스트림으로 처리하면, 코드 가독성이 높아진다
  • stream.parallel()은 병렬 처리를 지원한다. 속도를 높일 수 있다. 대용량 데이터를 처리할 때 좋다

스트림 병렬화

스트림은 병렬화 기능을 지원한다. 앞서 말했듯이 병렬화를 적용한다고 해서 무조건 성능이 좋아지는 것은 아니다. 심지어 결과가 잘못되거나 오동작할 수도 있다(safety failure). 병렬화를 적용하기 전에 이러한 케이스에 대해 잘 알아둬야 한다.

  • 스트림 병렬화는 (1) 연산을 쪼개서 수행한 후 (2) 합치는 방식으로 진행된다. 그래서 동작 방식이 종단인 연산에 대해서 성능이 좋아진다.
    ex) min, max, count, sum

  • 자료구조 중에 데이터가 메모리에 연속되어 저장된 경우 성능이 좋아진다. (참조 지역성이 뛰어난 자료구조를 써야 한다)
    ex) ArrayList, HashMap, HashSet, ConcurrentHashMap

  • 병렬화의 결과가 잘못되거나 오동작하는 것을 막기 위해서, 스트림의 reduce 연산에 건네지는 accumulator와 combiner는 결합법칙을 만족하고, 간섭받지 않고, 상태를 갖지 않아야 한다.
    ex) foreach(X) forEachOrdered(O)

느낀 점

  • 애초에 왜 parallel이 아닌 concurrent로 돌아가는 걸까 하는 근본적인 물음이 들었다. concurrent는 메모리 공유가 용이하다. 이 trade-off가 아닌지~

0개의 댓글