CompletableFuture는 비동기 프로그래밍에서 다양한 함수들을 제공하여 작업의 실행, 결과 처리, 작업 병합, 에러 처리 등을 간편하게 수행할 수 있도록 합니다. 아래에서 주요 함수들과 그 기능에 대해 설명하겠습니다.
1. 비동기 작업 실행
1.1 runAsync
• 결과값을 반환하지 않는 비동기 작업을 실행.
• 주로 Runnable을 실행할 때 사용.
• 기본적으로 ForkJoinPool을 사용하지만, Executor를 지정할 수도 있음.
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("비동기 작업 실행!");
});
1.2 supplyAsync
• 결과값을 반환하는 비동기 작업을 실행.
• 주로 Supplier를 실행할 때 사용.
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return "비동기 작업 결과";
});
2. 작업 완료 후 결과 처리
2.1 thenApply
• 작업 완료 후 결과를 받아 새로운 결과를 반환.
• Function을 사용하여 결과를 변환 가능.
future.thenApply(result -> result + " 변환됨")
.thenAccept(System.out::println);
2.2 thenAccept
• 작업 완료 후 결과를 받아 소비(출력, 저장 등)만 하고 반환값은 없음.
future.thenAccept(result -> {
System.out.println("결과 처리: " + result);
});
2.3 thenRun
• 작업 완료 후 결과를 사용하지 않고 단순 작업 실행.
future.thenRun(() -> {
System.out.println("작업 완료 후 실행");
});
3. 작업 조합 및 체이닝
3.1 thenCompose
• 이전 작업의 결과를 입력으로 받아 새로운 비동기 작업 실행.
• flatMap과 유사하며, CompletableFuture의 결과를 연결할 때 사용.
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = future1.thenCompose(result ->
CompletableFuture.supplyAsync(() -> result + " World")
);
future2.thenAccept(System.out::println); // Hello World
3.2 thenCombine
• 두 개의 CompletableFuture 결과를 조합하여 새로운 결과 생성.
• 두 작업이 모두 완료될 때 실행됨.
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
future1.thenCombine(future2, (result1, result2) -> result1 + " " + result2)
.thenAccept(System.out::println); // Hello World
3.3 allOf
• 여러 비동기 작업을 병렬로 실행하고, 모든 작업 완료 후 실행.
• 반환값은 CompletableFuture<Void>이므로 개별 결과는 수동으로 처리해야 함.
CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2);
allOf.thenRun(() -> System.out.println("모든 작업 완료"));
3.4 anyOf
• 여러 비동기 작업 중 하나라도 완료되면 실행.
• 반환값은 가장 먼저 완료된 CompletableFuture의 결과.
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future1, future2);
anyOf.thenAccept(System.out::println);
4. 에러 처리
4.1 exceptionally
• 작업 중 예외가 발생했을 때, 기본값 또는 대체 동작을 수행.
future.exceptionally(ex -> {
System.out.println("예외 처리: " + ex.getMessage());
return "대체 결과";
});
4.2 handle
• 작업 완료 후 결과 또는 예외를 처리.
• 결과와 예외를 동시에 처리할 수 있어 유용.
future.handle((result, ex) -> {
if (ex != null) {
System.out.println("예외 처리: " + ex.getMessage());
return "대체 결과";
}
return result + " 성공";
}).thenAccept(System.out::println);
5. 기타 유용한 함수들
5.1 complete
• 수동으로 작업 결과를 설정.
• 주로 테스트나 예외 상황에서 사용.
CompletableFuture<String> future = new CompletableFuture<>();
future.complete("수동 결과");
System.out.println(future.join()); // 수동 결과
5.2 join
• 작업이 완료될 때까지 대기하고 결과를 반환.
• get()과 유사하지만, ExecutionException 대신 CompletionException을 발생시킴.
String result = future.join();
5.3 isDone
• 작업이 완료되었는지 확인.
if (future.isDone()) {
System.out.println("작업 완료!");
}
6. 커스텀 Executor
모든 비동기 작업은 기본적으로 ForkJoinPool.commonPool()에서 실행됩니다. 커스텀 Executor를 지정하여 제어할 수도 있습니다.
Executor executor = Executors.newFixedThreadPool(4);
CompletableFuture.supplyAsync(() -> "Hello", executor)
.thenAcceptAsync(result -> System.out.println(result), executor);
요약
• 작업 실행: runAsync, supplyAsync
• 결과 처리: thenApply, thenAccept, thenRun
• 작업 조합: thenCompose, thenCombine, allOf, anyOf
• 에러 처리: exceptionally, handle
• 기타: complete, join, isDone
'spring' 카테고리의 다른 글
[Spring] Spring Boot에서 JAR 파일 활용 및 실행 과정 (0) | 2025.03.08 |
---|---|
[Spring] CompletableFuture 동작 예시 (2) | 2025.01.16 |
[Spring] CompletableFuture 등장 배경 (1) | 2025.01.16 |
[Spring] I/O 작업, CPU작업 (0) | 2025.01.06 |
[Spring] Spring에서의 동기 비동기 (0) | 2025.01.06 |