책 소개
요약
스칼라로 동시성 프로그램을 작성하는 방법을 다룬 책이지만, 꼭 스칼라 개발자가 아니더라도 JVM에서 동시성에 대한 기초를 쌓고, 동시 프로그래밍에 대한 지식을 넓히고자 하는 모든 프로그래머가 참고할 만한 훌륭한 기본서다.
이 책을 읽고 나면 기초적인 동기화 구성요소, 퓨처와 프라미스, 액터, 병렬 컬렉션, 반응형 확장(Rx)을 사용한 프로그래밍을 할 수 있고, 소프트웨어 트랜잭션 메모리 등을 활용해 복잡한 동시성 애플리케이션을 작성하는 법을 배울 수 있다.
추천의 글
동시, 병렬 프로그래밍은 주로 커널 프로그래밍이나 고성능 계산 등의 틈새 분야에 속했었지만, 능숙한 프로그래머라면 꼭 알아야만 하는 기술로 변해왔다. 이제는 병렬 분산 계산 시스템이 표준이기 때문에, 성능을 향상시키거나 비동기적인 이벤트를 처리하기 위한 대부분의 애플리케이션이 동시성 애플리케이션이다.
지금까지 대부분의 개발자는 이런 변화에 적응할 준비가 되어 있지 않았다. 학교에서 스레드와 락에 기반한 전통적인 동시성 모델을 배웠더라도, 그런 모델은 규모가 큰 동시성을 신뢰할 수 있게 다루면서 수긍할만한 생산성을 발휘하기에는 부적합해져 버렸다. 실제로 스레드와 락은 쓰기 어렵고, 올바르게 사용하기는 더욱 어렵다. 좋은 결과를 얻기 위해서는 더 고수준의 조합 가능한 동시성 추상화를 사용해야 할 필요가 있다.
15년 전에, 나는 스칼라의 아버지 뻘인 언어를 이용해 작업한 적이 있다. 그 언어는 ‘퍼널(Funnel)’이라는, 언어 핵심에서 동시성을 지원하는 실험적인 언어였다. 그 언어의 모든 프로그래밍 개념은 ‘병합 계산법(join calculus)’의 객체 지향적인 파생물인 ‘함수적 연결 (functional net)’ 위에 정의된 문법적 편의(syntatic sugar)로 설명할 수 있었다. 병합 계산법이 멋진 이론이긴 했지만, 몇 가지 실험을 거친 이후, 우리는 동시성 문제는 한 가지 정형화된 방식만으로 편하게 다루기에는 너무 다양한 측면이 존재한다는 점을 깨달았다. 모든 동시성 문제를 한꺼번에 해결할 수 있는 묘책은 없다. 올바른 해법은 목표가 무엇인가에 따라 달라진다. 값의 스트림이나 이벤트에 대해 반응하는 비동기 계산을 정의하고 싶은가? 메시지를 사용해 서로 통신하는 독립적이며 고립된 개체들이 있었으면 하는가? 변경 가능한 저장소에 대해 트랜잭션을 정의하고 싶은가? 아니면, 병렬 실행의 주 목적이 성능을 향상시키는 것인가? 이런 모든 과업에 대해 제대로 작동할 수 있는 추상화가 퓨처, 반응형 스트림, 액터, 트랜잭션 메모리, 병렬 컬렉션 등으로 따로 존재한다.
그로 인해 스칼라와 이 책이 필요해졌다. 유용한 동시성 추상화가 아주 많기 때문에, 이들을 모두 프로그래밍 언어의 구성 요소로 포함시키는 것은 매력적이지 않다. 스칼라에서 우리가 수행했던 작업의 이면에 있던 목적은, 사용자 코드나 라이브러리에서 고수준의 추상화를 쉽게 정의할 수 있게 하는 것이었다. 이런 방식을 통해, 프로그래머가 동시 프로그래밍의 다양한 측면을 처리할 수 있는 모듈을 정의할 수 있다. 이런 모듈은 모두 호스트 시스템이 제공하는 저수준의 핵심 기능을 바탕으로 구축될 것이다. 뒤돌아보면, 이런 접근 방식이 매우 잘 들어맞아왔다. 오늘날 스칼라로 된 강력하고 우아한 동시 프로그래밍 라이브러리를 다수 볼 수 있다. 이 책은 그중 가장 중요한 몇 가지를 알려주고, 각각의 용례와 적용 패턴을 설명할 것이다.
이러한 책의 저자로 알렉산더 프로코펙보다 더 나은 전문가는 없을 것이다. 그는 동시성과 병렬 프로그래밍에 가장 유명한 몇몇 스칼라 라이브러리에 공헌했다. 또, 가장 복잡한 데이터 구조와 알고리즘을 여러 개 고안해냈다. 그는 자신이 작업해 온 분야에 대해, 읽기 쉬운 자습서인 동시에 권위 있는 참고서 역할을 할 수 있는 책을 만드는 데 성공했다. 나는 이 책이 스칼라로 동시, 병렬 프로그램을 작성하고자 하는 모든 사람에게 필독서가 될 것으로 믿는다. 또한, 환상적이며 빠르게 변하고 있는 계산 분야인 동시 프로그래밍에 대해 알고 싶어 하는 많은 사람의 서가에 이 책이 꽃혀 있는 것을 보게 되리라 확신한다.
-마틴 오더스키(Martin Odersky) /
EPFL 교수, 타입세이프(Typesafe) 공동창업자, 스칼라 창시자
이 책에서 다루는 내용
■ JVM의 동시성 모델에 초점을 맞춘 최신 다중 프로세서 시스템상의 동시 프로그래밍
■ 간단한 저수준 동시성 기본 구성요소로 고성능 동시 시스템 구축
■ 퓨처와 프라미스를 사용해 비동기적 동시 계산을 표현하는 방법
■ 데이터-병렬 컬렉션을 사용해 순차적 프로그램을 매끄럽게 병렬로 빨리 수행하는 법
■ Rx 스타일의 이벤트 스트림을 활용해 선언적으로 반응형 이벤트 기반 프로그램 구현
■ 안전하고, 규모 확장성이 있으며, 이해하기 쉬운 메모리 트랜잭션 데이터 모델 설계
■ 여러 기계에서 실행될 수 있는 분산 애플리케이션을 투명하게 작성하는 법
■ 대규모 애플리케이션에서 적절한 분산 추상화 방식을 선택하고, 여러 분산 프레임워크를 통합하는 방법
이 책의 대상 독자
이 책은 스칼라로 동시 프로그램을 작성하고 싶거나, 동시성에 대한 지식을 넓히고 싶은 소프트웨어 개발자에게 꼭 필요한 자습서다.
동시성에 대해 알지 못하는 스칼라 프로그래머를 대상으로 할 뿐 아니라, 이미 동시성에 대해 알고 있지만 좀 더 자세히 알고 싶은 프로그래머도 대상으로 한다. 스칼라에 대해 기본적인 지식이 있다면 도움이 될 것이다. 하지만, 자바 등 다른 언어를 잘 알고 있는 개발자도 쉽게 이 책을 읽을 수 있다.
이 책의 구성
이 책은 동시 프로그래밍의 다양한 주제를 다루는 장들로 이뤄졌다. 스칼라 런타임의 일부인 기본 동시성 API를 다루며, 더 복잡한 동시성 구성요소를 소개하고, 고수준 동시성 추상화에 대해 자세히 소개한다.
1장, ‘소개’에서는 동시 프로그래밍의 필요성을 설명하고, 철학적 배경을 제공한다. 그와 동시에, 이 책의 나머지 부분을 이해하기 위해 필요한 스칼라 언어 기초를 다룬다.
2장, ‘JVM상의 동시성과 자바 메모리 모델’에서는 동시 프로그래밍의 기초를 설명한다. 이 장에서는 스레드(thread)를 사용하는 방법과 공유 메모리에 대한 접근을 보호하는 방법을 배워보고, 자바 메모리 모델을 알아본다.
3장, ‘전통적인 동시 프로그래밍 구성 블록’에서는 스레드 풀(thread pool), 원자적 변수(atomic variable), 동시 컬렉션(concurrent collection) 등의 전통적인 동시성 도구에 대해, 특히 그들이 스칼라 언어의 특징과 어떻게 상호작용하는가에 초점을 맞춰서 제시한다. 이 책은 최신의 고수준 동시 프로그래밍 프레임워크에 중점을 둔다. 따라서 이 장은 전통적인 프로그래밍 기법에 대한 개괄을 제공하지만, 너무 많은 것을 세세히 다루지는 않는다.
4장, ‘퓨처와 프라미스를 사용한 비동기적 프로그래밍’에서는 스칼라용 동시성 프레임워크를 설명하는 첫 번째 장이다. 이 장에서는 퓨처(future)와 프라미스(promise) API를 소개하고, 비동기 프로그램을 작성할 때 어떻게 이들을 제대로 사용하는지 보여준다.
5장, ‘데이터 병렬 컬렉션’에서는 스칼라의 병렬 컬렉션 프레임워크를 설명한다. 컬렉션 연산을 병렬화하는 방법과 언제 병렬화가 가능한지, 어떻게 병렬화의 이점을 평가할 수 있는지를 배워본다.
6장, ‘반응형 확장을 활용한 동시 프로그래밍’에서는 이벤트 기반이나 비동기 프로그래밍에서 반응형 확장(Reactive Extension)을 사용하는 방법을 설명한다. 이벤트 스트림에 대한 연산이 컬렉션 연산과 어떻게 대응하는지와, 한 스레드에서 다른 스레드로 이벤트를 전달하는 방법, 이벤트 스트림을 사용해 반응형 사용자 인터페이스를 설계하는 방법을 알아본다.
7장, ‘소프트웨어 트랜잭션 메모리’에서는 트랜잭션 프로그래밍을 위한 라이브러리인 스칼라 STM(ScalaSTM)을 소개한다. 트랜잭션 프로그래밍의 목표는 안전하고 더 직관적인 공유 메모리 프로그래밍 모델을 제공하는 것이다. 공유 데이터에 대한 접근을 규모 확장성이 있는 메모리 트랜잭션을 사용해 보호함과 동시에 교착상태(deadlock)나 경합 조건(race condition)을 감소시키는 방법을 배워본다.
8장, ‘액터’에서는 액터 프로그래밍 모델(actor programming model)과 아카(Akka) 프레임워크를 보여준다. 여러 기계에서 실행되는 메시지 전달(message passing) 분산 프로그램을 어떻게 투명하게 만들 수 있는지 살펴본다.
9장, ‘동시성 실제 활용’에서는 앞에서 소개한 모든 동시성 라이브러리를 정리한다. 이 장에서는 주어진 문제를 해결하기 위해 적절한 동시성 추상화를 어떻게 선택하는지와 여러 다른 동시성 추상화를 함께 사용해 대규모 동시성 애플리케이션을 설계하는 방법을 알아본다..
각 장을 순서대로 읽을 것을 권장하지만, 반드시 그래야 할 필요는 없다. 2장의 내용에 익숙한 독자는 나머지 내용을 바로 공부할 수 있을 것이다. 앞에서 다뤘던 내용에 깊이 의존하는 유일한 장은 9장이며, 이 책에서 다룬 주제를 실용적으로 정리한다.
목차
목차
- 1 소개
- 동시 프로그래밍
- 전통적인 동시성 소개
- 최근의 동시성 패러다임
- 스칼라의 이점
- 스칼라 기초 지식
- 스칼라 프로그램 실행 모델
- 스칼라 기초
- 요약
- 연습문제
- 동시 프로그래밍
- 2 JVM상의 동시성과 자바 메모리 모델
- 프로세스와 스레드
- 스레드 만들고 시작
- 원자적 실행
- 재배열
- 모니터와 동기화
- 교착상태
- 가드가 있는 락
- 스레드 인터럽트와 부드럽게 종료
- 볼레타일 변수
- 자바 메모리 모델
- 변경 불가능한 객체와 파이널 필드
- 요약
- 연습문제
- 프로세스와 스레드
- 3 전통적인 동시 프로그래밍 구성 블록
- Exucutor와 ExecutionContext 객체
- 원자적 구성 요소
- 원자적 변수
- 락이 없는 프로그래밍
- 락을 명시적으로 구현
- ABA 문제
- 지연 값
- 동시성 컬렉션
- 동시성 큐
- 동시성 집합과 맵
- 동시성 순회
- 프로세스를 만들고 다루기
- 요약
- 연습문제
- 4 퓨처와 프라미스를 사용한 비동기적 프로그래밍
- 퓨처
- 퓨처 계산 시작
- 퓨처 콜백
- 퓨처와 예외
- Try 타입 사용
- 심각한 예외
- 퓨처를 함수적으로 합성
- 프라미스
- 콜백 기반의 API 변환
- 퓨처 API 확장
- 비동기적 계산 취소
- 퓨처와 블로킹
- 퓨처 기다리기
- 비동기 계산 블록
- 스칼라 비동기 라이브러리
- 다른 퓨처 프레임워크들
- 요약
- 연습문제
- 퓨처
- 5 데이터 병렬 컬렉션
- 스칼라 컬렉션 간단 정리
- 병렬 컬렉션 사용
- 병렬 컬렉션 계층 구조
- 병렬성 수준 설정
- JVM상의 성능 측정
- 병렬 컬렉션 사용시 주의할 점
- 병렬화 불가능한 컬렉션
- 병렬화 불가능한 연산
- 병렬 연산에서 부수 효과 사용
- 비결정적 병렬 연산
- 연산자의 교환성과 결합성
- 병렬과 동시 컬렉션을 함께 사용
- 약한 일관성 이터레이터
- 원하는 대로 동시 컬렉션 구현
- 분할기
- 병합기
- 다른 데이터 병렬 프레임워크
- 스칼라블리츠의 컬렉션 계층 구조
- 요약
- 연습문제
- 6 반응형 확장을 활용한 동시 프로그래밍
- Observable 객체 생성
- Observable과 예외
- Observable 계약 조건
- 전용 Observable 객체 구현
- 퓨처에서 Observable 생성
- Subscription
- Observable 객체 합성
- 내포된 Observable
- Observable에서 발생한 오류 처리
- Rx 스케줄러
- UI 애플리케이션을 위해 전용 스케줄러 사용
- 서브젝트와 하향식 반응형 프로그래밍
- 요약
- 연습문제
- Observable 객체 생성
- 7 소프트웨어 트랜잭션 메모리
- 원자적 변수의 문제점
- 소프트웨어 트랜잭션 메모리 사용
- 트랜잭션형 참조
- atomic 문 사용
- 트랜잭션 합성
- 트랜잭션과 부수 효과의 상호작용
- 단일 연산 트랜잭션
- 트랜잭션 내포시키기
- 트랜잭션과 예외
- 트랜잭션 재시도
- 타임아웃 정해서 재시도
- 트랜잭션형 컬렉션
- 트랜잭션 지역 변수
- 트랜잭션형 배열
- 트랜잭션형 맵
- 요약
- 연습문제
- 8 액터
- 액터로 작업
- 액터 시스템과 액터 생성
- 처리하지 않는 메시지 관리
- 액터의 행동 방식과 상태
- 아카의 액터 계층 구조
- 액터 식별
- 액터의 생명 주기
- 액터 사이의 통신
- 물어보기 패턴
- 전달 패턴
- 액터 멈추기
- 액터 관리
- 원격 액터
- 요약
- 연습문제
- 액터로 작업
- 9 동시성 실제 활용
- 목적에 따라 적절한 도구 선택
- 하나로 모으기 - 원격 파일 브라우저
- 파일시스템 모델링
- 서버 인터페이스
- 클라이언트 파일 방문 API
- 클라이언트 사용자 인터페이스
- 클라이언트 논리 구현
- 원격 파일 브라우저 개선
- 동시 프로그램 디버깅
- 교착상태와 진행되지 않음
- 잘못된 프로그램 출력 디버깅
- 성능 디버깅
- 요약
- 연습문제
도서 오류 신고
정오표
정오표
2016. 5. 25 수정사항
[p.74: 마지막 행]
다음 그림의 오른쪽과 같이 실행되는 경우여야 한다.
->
다음 그림의 왼쪽과 같이 실행되는 경우여야 한다.
2016. 7. 7 수정사항
[p.366: 아래에서 8행]