반응형
CompletableFuture란?
- Future와 CompletionStage를 구현한 클래스
- 비동기 처리를 쉽게 처리할 수 있는 방법을 제공한다.
- 여러 CompletableFuture를 병렬로 처리하거나 병합 처리, 취소, 에러 처리 등을 제공한다.
기본 사용법
CompletableFuture<String> future = new CompletableFuture<>();
new Thread(() -> {
log("run");
future.complete("Hello World");
}).start();
log("result : " + future.get());
[11:39:41.021406][Thread-0] run
[11:39:41.037362900][main] result : Hello World
completedFuture()
- 이미 활용할 데이터가 있을 경우 사용.
CompletableFuture<String> future = CompletableFuture.completedFuture("Hello World");
log("result : " + future.get());
[11:40:45.714630200][main] result : Hello World
cancel()
- cancel() 호출시 get()에서 CancellationException이 발생할 수 있어 예외처리를 해주어야 한다.
CompletableFuture<String> future = new CompletableFuture<>();
new Thread(() -> {
log("run");
future.cancel(false);
}).start();
try {
log("result : " + future.get());
} catch (CancellationException e) {
log("error : " + e);
}
[11:42:56.248613200][Thread-0] run
[11:42:56.263574100][main] error : java.util.concurrent.CancellationException
handle()
- 예외 처리를 위한 기능을 제공한다.
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> {
log("future");
throw new IllegalStateException("ERROR");
})
.handle((text, throwable) -> {
log("error : " + throwable);
return "Error";
});
[11:48:37.049525100][ForkJoinPool.commonPool-worker-19] future
[11:48:37.066478500][ForkJoinPool.commonPool-worker-19] error : java.util.concurrent.CompletionException: java.lang.IllegalStateException: ERROR
[11:48:37.067475300][main] result : Error
supplyAsync()
- 직접 스레드 생성하지 않고 비동기 처리가 가능하게 해준다.
- 데이터를 리턴해주어야 할 때 사용한다.
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> {
log("future");
return "Hello World";
});
log("result : " + future.get());
[11:43:45.796556500][ForkJoinPool.commonPool-worker-19] future
[11:43:45.811515900][main] result : Hello World
runAsync()
- supplyAynsc()와 동일
- 데이터를 리턴해줄 필요 없을 때 사용한다.
CompletableFuture<Void> future = CompletableFuture
.runAsync(() -> {
log("future");
});
log("result : " + future.get());
[11:45:25.319738500][ForkJoinPool.commonPool-worker-19] future
[11:45:25.334797400][main] result : null
thenApply()
- supplyAsync()의 처리 결과를 활용해 후처리 작업을 해야할 때 사용한다.
- 결과값을 리턴해야할 경우 사용.
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> {
sleep(1000);
log("supplyAsync");
return "Hello World";
})
.thenApply((text) -> {
sleep(1000);
log("thenApply");
return text + "!";
});
log("result : " + future.get());
[11:53:47.213973300][ForkJoinPool.commonPool-worker-19] supplyAsync
[11:53:48.233912400][ForkJoinPool.commonPool-worker-19] thenApply
[11:53:48.240899900][main] result : Hello World!
thenAccept()
- thenApply()와 동일.
- 결과값 리턴이 필요 없을 경우 사용.
CompletableFuture<Void> future = CompletableFuture
.supplyAsync(() -> {
sleep(1000);
log("supplyAsync");
return "Hello World";
})
.thenAccept((text) -> {
sleep(1000);
log("thenAccept");
});
log("result : " + future.get());
[11:55:05.767468500][ForkJoinPool.commonPool-worker-19] supplyAsync
[11:55:06.789277100][ForkJoinPool.commonPool-worker-19] thenAccept
[11:55:06.791285600][main] result : null
thenCommpose()
- 여러 작업을 순차적으로 수행할 때 사용한다.
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> {
sleep(1000);
log("supplyAsync");
return "Hello";
})
.thenCompose((text) -> CompletableFuture.supplyAsync(() -> {
sleep(1000);
log("thenCompose1");
return text + " World";
}))
.thenCompose((text) -> CompletableFuture.supplyAsync(() -> {
sleep(1000);
log("thenCompose2");
return text + " Java";
}));
log("result : " + future.get());
[11:57:24.933529100][ForkJoinPool.commonPool-worker-19] supplyAsync
[11:57:25.959989][ForkJoinPool.commonPool-worker-5] thenCompose1
[11:57:26.972361900][ForkJoinPool.commonPool-worker-5] thenCompose2
[11:57:26.978944700][main] result : Hello World Java
thenCombine()
- 여러 작업을 동시에 수행할 때 사용한다.
CompletableFuture<String> future1 = CompletableFuture
.supplyAsync(() -> {
sleep(1000);
log("future1");
return "Hello";
});
CompletableFuture<String> future2 = CompletableFuture
.supplyAsync(() -> {
sleep(1000);
log("future2");
return "World";
});
CompletableFuture<String> future = future1.thenCombine(future2, (text1, text2) -> text1 + " " + text2);
log("result : " + future.get());
[12:01:06.897832500][ForkJoinPool.commonPool-worker-19] future1
[12:01:06.897832500][ForkJoinPool.commonPool-worker-5] future2
[12:01:06.919774300][main] result : Hello World
anyOf()
- 빨리 처리되는 1개의 결과만 가져오는 메소드
CompletableFuture<String> future1 = CompletableFuture
.supplyAsync(() -> {
sleep(3000);
log("future1");
return "Hello";
});
CompletableFuture<String> future2 = CompletableFuture
.supplyAsync(() -> {
sleep(2000);
log("future2");
return "World";
});
CompletableFuture<String> future3 = CompletableFuture
.supplyAsync(() -> {
sleep(1000);
log("future3");
return "Java";
});
CompletableFuture<Object> future = CompletableFuture.anyOf(future1, future2, future3);
log("result : " + future.get());
[12:32:22.200336600][ForkJoinPool.commonPool-worker-23] future3
[12:32:22.214299300][main] result : Java
allOf()
- 모든 future의 결과를 받아서 처리하는 메소드
CompletableFuture<String> future1 = CompletableFuture
.supplyAsync(() -> {
sleep(3000);
log("future1");
return "Hello";
});
CompletableFuture<String> future2 = CompletableFuture
.supplyAsync(() -> {
sleep(2000);
log("future2");
return "World";
});
CompletableFuture<String> future3 = CompletableFuture
.supplyAsync(() -> {
sleep(1000);
log("future3");
return "Java";
});
CompletableFuture<Void> future = CompletableFuture.allOf(future1, future2, future3);
String result = Stream.of(future1, future2, future3)
.map(CompletableFuture::join)
.collect(Collectors.joining(", "));
log("get() : " + future.get());
log("future1.isDone() : " + future1.isDone());
log("future2.isDone() : " + future2.isDone());
log("future3.isDone() : " + future3.isDone());
log("result : " + result);
[12:37:57.561345][ForkJoinPool.commonPool-worker-23] future3
[12:37:58.556364200][ForkJoinPool.commonPool-worker-5] future2
[12:37:59.562620500][ForkJoinPool.commonPool-worker-19] future1
[12:37:59.564619][main] get() : null
[12:37:59.566400100][main] future1.isDone() : true
[12:37:59.566400100][main] future2.isDone() : true
[12:37:59.566400100][main] future3.isDone() : true
[12:37:59.567397300][main] result : Hello, World, Java
참고
반응형
'Development > Java' 카테고리의 다른 글
[Java] Shell Command 실행하기 (0) | 2021.08.28 |
---|---|
[Java] Date (0) | 2021.07.24 |
[Java] Annotation Processor (0) | 2021.03.04 |
[Java] Reflection (0) | 2021.03.03 |
[Java] Simple Machine Learning (0) | 2021.02.27 |