자바 7에서는 분할, 정복 알고리즘의 포크/조인 구현을 지원하는 java.util.concurrent.RecursiveTask
가 추가되었고 자바 8에서는 스트림과 새로 추가된 람다 지원에 기반한 병렬 프로세싱이 추가 되었다.
자바는 Future를 조합하는 기능을 추가하면서 동시성을 강화했고, 자바 9에서는 분산 비동기 프로그래밍을 명시적으로 지원한다.
이들 API는 매쉬업 애플케이션, 즉 다양항 웹 서비스를 이용하고 이들 정보를 실시간으로 조합해 사용자에게 제공하거나 추가 웹 서비스를 통해 제공하는 종류의 애플리케이션을 개발하는데 필수적인 기초 모델과 툴킷을 제공한다. 이 과정을 리액티브 프로그래밍
이라고 부르며 자바 9에서는 발행-구독 프로토콜(java.util.concurrent.Flow
인터페이스 추가)로 이를 지원한다. CompletableFuture
와 java.util.concurrent.Flow
의 궁극적인 목표는 가능한한 동시에 실행할 수 있는 독립적인 태스크를 가능하게 만들면서 멀티코어 또는 여러 기기를 통해 제공되는 병렬성을 쉽게 이용하는 것이다.
쓰레드 실행은 메서드를 호출한 다음의 코드와 동시에 실행되므로 데이터 경쟁 문제를 일으키지 않도록 주의해야 한다.
기존 실행 중이던 쓰레드가 종료되지 않은 상황에서 자바의 main() 메서드가 반환하면 어떻게 될까?
두가지 방법 전부 안전하지 못하다.
첫 번째 방법에서는 종료를 못한 쓰레드에 의해 애플리케이션이 충돌될 수 있다. 또 다른 문제로 디스크에 쓰기 I/O 작업을 시도하는 일련의 작업을 중단했을 때 이로 인해 외부 데이터의 일관성이 파괴될 수 있다.
이 문제를 피하려면 만든 모든 쓰레드를 추적하고 애플리케이션을 종료하기 전에 쓰레드 풀을 포함한 모든 쓰레드를 종료하는 것이 좋다.
Future나 리액티브 형식의 비동기 API에서 호출된 메서드의 실제 바디는 별도의 스레드에서 호출되며 이때 발생하는 어떤 에러는 이미 호출자의 실행 범위와는 관계가 없는 상황이 된다.
Future를 구현한 CompletableFuture에서는 런타임 get() 메서드에 예외를 처리할 수 있는 기능을 제공하며 예외에서 회복할 수 있도록 exceptionally() 같은 메서드도 제공한다.