IT 서적/모던 자바 인 액션

모던 자바 인 액션

수달하나 2023. 9. 8. 23:50

Chapter 15 CompletableFuture와 리액티브 프로그래밍 컨셉의 기초


멀티코어 프로세서가 발전함과 동시에 애플리케이션의 속도는 멀티코어 프로세서를 얼마나 잘 활용할 수 있도록 소프트웨어를 개발하는가에 따라 달라질 수 있다는 것이 확인 되었고 마이크로서비스 와 같은 아키텍처의 선택이 지난 몇 년간 증가하면 멀티태스크 프로그래밍에 대한 중요성이 증가되었다.
 
동시성 VS 병렬성
동시성은 하나의 코어에서 여러개의 작업을 진행 병렬성은 여러개의 코어에서 여러개의 작업을 진행.
동시성을 잘 활용할 수 있도록 Future 인터페이스를 이용하여 CompletableFuture 를 구현하여 사용 할 수 있도록 한다. 


15.1 동시성을 구현하는 자바 지원의 진화

 
스레드를 이용하여 동시에 또는 협력적으로 프로그램을 실행할 수 있다.
병렬 스트림 반복은 명시적으로 쓰레드를 사용하는 것에 비해 높은 수준의 개념이라는 사실을 확인 할 수 있고 스트림을 이용해서 스레드 사용 패턴을 추상화 할 수 있다.
Excutor 프레임워크와 스레드 풀을 통해서 스레드를 높은 수준으로 끌어올리게 되었다.
 
동기 API, 비동기 API
- Thread 를 다루는 저 수준의 API 호출은 객체지향적 프로그래밍으로써 좋은 코드가 아닐 수 있다.
명시적인 submit과 같은 메서드 호출은 명시적 반복을 통한 병렬화 수행을 지시하기 때문에 내부 반복으로 바꾼 것과 같은 함수형 프로그래밍 적으로 해결하는 것이 좋다.
 
리액티브 형식 API
- 비동시 / 변화 혹은 변경 요소를 중심으로 변화된 양상을 바로바로 전파하는 프로그램을 리액티브 프로그래밍이라고 한다. 리액티브 형식의 API 는 보통 한 결과가 아니라 일련의 이벤트에 반응하도록 설계되었으므로 Future 인터페이스로 설계하는 것이 바람직하다.
 
잠자기는 해로운것으로 간주
- 스레드는 잠들어도 여전히 시스템 자원을 점유한다. 스레드 풀에서 잠자는 스레드만 실행을 막는것이 아니고 블록 동작도 마찬가지로 자원을 점유한 상태로 아무 동작도 취하지 않는다. 하지만 ScheduledExcutorService 와 같은 구현을 이용하여 자원을 점유하지 않은 상태로 실행을 대기 시킬 수 있고 이러한 방식을 사용 하는 것이 자원을 분배함에 있어서 좀 더 효율적일 수 있다. 


15.6 리액티브 시스템 vs 리액티브 프로그래밍

 

리액티브 시스템은 런타임 환경이 변화에 애응하도록 전체 아키텍처가 설계된 프로그램을 가리킨다.


Chapter 16 CompletableFuture : 안정적 비동기 프로그래밍


16.1 Future 의 단순 활용


Future의 get 메서드로 결과를 가벼올 수 있는데 get 메서드를 호출했을 때 이미 계산이 완료되어 결과가 준비되었다면 즉시 결과를 반환하지만 결과가 준비되지 않았다면작업이 완료될 때 까지 해당 쓰레드를 블록시킨다.
오래 걸리는 작업이 영원히 끝나지 않으면 문제가 발생할 수 있으므로 get메서드를 오버로드해서 해당 스레드가 대기할 최대 타임아웃 시간을 설정하는 것이 좋다.

동기 API와 비동기 API
동기 API를 사용하는 상황이 블록호출, 비동기 API를 사용하는 상황을 비블록 호출 이라고 한다.


16.2 비동기 API 구현


비동기 연산의 경우 계산의 결과를 표현 할 수 있는 Future 인터페이스를 제공한다.
클라이언트가 Future의 get 메서드를 호출하면 Future가 결과값을 가지고 있다면 Future에 포함된 값을 읽거나 아니면 값이 계산될 때 까지 블록한다.

에러 처리 방법
쓰레드가 계산을 진행하는 동안 에러가 발생하는 시나리오를 대비해야 한다.
일반적으로 문제가 발생하면 발생한 에러를 포함시켜 Future를 종료 할 수 있도록 한다.


16.3 비블록 코드 만들기


비동기 연산과 stream 을 통한 계산
CompletableFuture 와 stream을 통해서 하나의 파이프라인으로 연산을 처리하여 모든 요청 동작이 비동기적이며 비 순차적으로 처리될 수 있도록 해야 한다.

결과적으로 Excutor로 스레드 풀의 크기를 조절하는 등 애플리케이션에 맞는 최적화된 설정을 만들어서 애플리케이션의 성능을 실제로 향상시킬 수 있는지 확인해야 한다.


16.4 비동기 작업 파이프라인 만들기


CompletableFuture API 두 비동기 연산을 파이프라인으로 만들 수 있도록 thenCompose 메서드를 제공한다.
첫 번째 CompletableFuture 반환 결과를 인수로 받아서 두 번째 CompletableFuture를 반환하는 과정에 있어서 두 번째 CompletableFuture는 첫 번째 CompletableFuture의 결과를 계산의 입력으로 사용한다.

Async 메서드 사용
Async로 끝나지 않은 메서드는 이전 작업을 수행한 스레드와 같은 스레드에서 작업을 실행함을 의미하고 Async로 끝나는 메서드는 다음 작업이 다른 스레드에서 실행되도록 스레드 풀로 작업을 제출한다.