Java에서 비동기 프로그래밍은 높은 성능과 확장성을 필요로 하는 애플리케이션에서 필수적인 요소입니다. 비동기 처리를 통해 I/O 작업을 효율적으로 수행하고, 응답 시간을 단축할 수 있습니다. Java는 CompletableFuture
와 Reactive Streams
를 활용하여 비동기 프로그래밍을 효과적으로 구현하는 방법에 대해 알아 보겠습니다.
1. Java에서 비동기 프로그래밍이 필요한 이유
1) 블로킹(Blocking) vs. 비블로킹(Non-Blocking)
Thread.sleep()
사용)CompletableFuture
)2) 비동기 프로그래밍의 장점
Java는 CompletableFuture
와 Reactive Streams
를 활용하여 이러한 문제를 해결합니다.
2. CompletableFuture를 이용한 비동기 처리
1) 기본적인 CompletableFuture 사용법
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
return "Hello, CompletableFuture!";
}).thenAccept(System.out::println);
}
}
supplyAsync()
는 별도의 스레드에서 실행합니다.thenAccept()
를 사용해 결과가 준비되면 실행합니다.2) 여러 작업을 병렬 실행하기
import java.util.concurrent.CompletableFuture;
public class ParallelTasks {
public static void main(String[] args) {
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> "Task 1 완료");
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> "Task 2 완료");
task1.thenCombine(task2, (result1, result2) -> result1 + " & " + result2)
.thenAccept(System.out::println);
}
}
thenCombine()
을 사용하여 두 개의 작업을 동시에 실행하고 결과를 조합을 합니다.3) 예외 처리
CompletableFuture.supplyAsync(() -> {
if (Math.random() > 0.5) throw new RuntimeException("에러 발생");
return "성공";
}).exceptionally(ex -> "예외 발생: " + ex.getMessage())
.thenAccept(System.out::println);
exceptionally()
를 활용하여 예외 발생 시 대체 값 제공합니다.3. Reactive Streams를 이용한 비동기 처리
1) Reactive Streams란?
Reactive Streams는 비동기 데이터 흐름을 처리하는 표준 API입니다. 주요 구현체로는 Project Reactor(Spring WebFlux), RxJava 등이 있습니다.
Reactive Streams의 주요 개념:
2) Reactor를 활용한 비동기 스트림 처리
import reactor.core.publisher.Flux;
public class ReactiveExample {
public static void main(String[] args) {
Flux.just("데이터 1", "데이터 2", "데이터 3")
.map(String::toUpperCase)
.subscribe(System.out::println);
}
}
Flux.just()
는 여러 개의 데이터를 스트림으로 생성합니다.map()
을 통해 데이터를 변환 가능합니다.subscribe()
를 호출해야 데이터가 전송됩니다.3) 비동기 데이터 스트림 결합하기
import reactor.core.publisher.Mono;
public class ReactiveCombine {
public static void main(String[] args) {
Mono<String> task1 = Mono.just("Task 1 완료");
Mono<String> task2 = Mono.just("Task 2 완료");
task1.zipWith(task2, (result1, result2) -> result1 + " & " + result2)
.subscribe(System.out::println);
}
}
Mono.zipWith()
를 사용하여 두 개의 작업을 병렬로 실행하고 결과를 결합합니다.4) 백프레셔(Backpressure) 처리
Reactive Streams는 과도한 데이터 흐름을 조절하는 백프레셔(Backpressure) 개념을 지원합니다.
Flux.range(1, 1000)
.onBackpressureDrop()
.subscribe(System.out::println);
onBackpressureDrop()
을 사용하면 처리할 수 없는 데이터는 자동으로 폐기됩니다.4. CompletableFuture vs. Reactive Streams 비교
기능 | CompletableFuture | Reactive Streams |
---|---|---|
동시 실행 | O | O |
데이터 스트림 처리 | X | O |
콜백 기반 | O | O |
백프레셔 지원 | X | O |
사용 용도 | 단일 작업 비동기 처리 | 대량 데이터 흐름 처리 |
CompletableFuture
는 단일 또는 병렬 작업을 수행할 때 적합합니다.Reactive Streams
는 대량의 데이터를 실시간으로 처리할 때 유용합니다.결론
Java의 비동기 처리인 CompletableFuture와 Reactive Streams에 대해 알아 보겠습니다. Java의 비동기 프로그래밍은 성능 최적화와 응답 시간 단축에 필수적인 요소이며, CompletableFuture
는 단일 작업의 비동기 실행에 적합하며, Reactive Streams
는 대규모 데이터 스트림 처리에 유용하니 이 방법을 배워 효율적인 프로그램을 개발해 보시길 바랍니다.
일상에서 벗어나 진정한 휴식을 꿈꾼다면, 일본 하코네 온천 료칸만큼 매력적인 여행지도 드물 것입니다. 하지만 검색만…
디즈니랜드 여행을 앞두고 가장 중요한 고민 중 하나는 바로 “숙소 선택”입니다. 꿈같은 하루를 선물하고 싶은…
스이카 카드 발급 해야하는 이유 "도쿄 지하철 정복은 스이카 카드 없으면 절대 불가능합니다!" "이 카드…
리버 크루즈를 타야만 하는 이유 "오사카 여행에서 낮에는 활기찬 거리, 밤에는 화려한 네온사인으로 물든 도시를…
오사카 여행에 필수적인 교통패스인 오사카 교통패스에 대해 소개 하겠습니다. 일본 오사카 여행을 준비 중이시라면, 효율적인…
후쿠오카는 일본 여행지 중에서도 근교 여행지와 맛집, 쇼핑, 자연 풍경, 도시를 한 번에 즐길 수…