일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- GIT
- JS
- 코딩테스트
- STS
- Java
- 유레카
- 스프링 클라우드
- 자바
- docker
- SpringBoot
- spring boot
- 도커
- 비동기
- JavaScript
- Spring Cloud
- jQuery
- map()
- map
- gitlab
- 프로그래머스
- IntelliJ
- Spring
- spring security
- date
- leetcode
- OAuth
- 스프링
- 스프링부트
- EUREKA
- 자바스크립트
- Today
- Total
RATSENO
CompletableFuture<T> -2 본문
이전 포스팅에 이어서, 논블로킹 방식으로 사용하기 위한 콜백 방식에 대해서 정리해보겠습니다.
이전까지는 비동기로 호출하였지만, get() 또는 join()을 호출함으로써
응답 값을 받을 때까지 블로킹이 되었습니다.
하지만 이러한 동작은 저희가 원하는 모습이 아닙니다.
흐름을 방해 받고 싶지 않습니다.
그래서 저희는 응답값이 리턴되면, 어떠한 행위를 하도록 정의할 것입니다.
이러한 것을 콜백 방식이라고 합니다.
프런트엔드 개발 시에 많이 쓰이기 때문에 익숙하실 것 같습니다.
예를 들자면
window.setTimeout(function(){
console.log("3초 뒤에 실행");
}, 3000);
이러한 모습이라던가,
또는 이어서 보여드릴 메서드와 유사하게 생긴 Promise()의 .then() 메서드가 있습니다.
ratseno.tistory.com/22?category=781442
//3초뒤에 1을 return
function asyncTest(){
return new Promise(function(resolve, reject){
setTimeout(function(){
resolve(1);
}, 3000);
});
};
asyncTest()
.then(function(res){
//3초뒤에 return받은 1을 사용
console.log(1+"을 받았습니다.");
});
//1을 받았습니다
CompletableFuture<Void> thenAccept(Consumer<? super T> action)
위에서 잠깐 살펴보았던 Promise의 .then() 메서드와 아주 유사하게 생겼습니다.
사용법도 동일합니다. 비동기로 호출한 메서드가 실행되고 결과값이 리턴 또는 동작이 완료되었을 때,
실행될 콜백 함수를(Consumer <? super T> action) 정의하면 됩니다.
리턴 타입에서 볼 수 있듯이 thenAccept는 Void 리턴 값이 없습니다.
@Test
public void 비동기_방식_논블록킹_되는_콜백방식_ID조회하기_thenAccept(){
CompletableFuture<Void> completableFuture = memberService.getMemberIdAsync_supplyAsync("철수")
.thenAccept(integer -> {
log.info("리턴값이 없는 thenAccept");
log.info("회원 ID:" + integer);
});
log.info("아직 최종 데이터를 전달 받지는 않았지만, 다른작업 수행가능");
/*메인 스레드가 끝나는것을 방지하기 위한 코드*/
Assert.assertNull(completableFuture.join());
}
supplyAsync() 메서드를 호출하여 3초 뒤 값이 리턴되면, log를 찍는 콜백 함수입니다.
해당 샘플에서는 리턴 값을 사용하기 위해 supplyAsync()를 사용하였지만, runAsync()도 사용 가능합니다.
<U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
thenApply는 thenAccept와 다르게 리턴 값이 있는 메서드입니다. thenAccept와 함께 사용 가능합니다.
@Test
public void 비동기_방식_논블록킹_되는_콜백방식_ID조회하기_thenApply(){
CompletableFuture<Void> completableFuture = memberService.getMemberIdAsync_supplyAsync("철수")
.thenApply(integer -> {
log.info("리턴값이 있는 thenApply");
log.info("회원 ID:" + integer);
return integer;
})
.thenAccept(result -> {
log.info("리턴값이 없는 thenAccept");
log.info("회원 ID:" + result);
Assert.assertEquals(1, result.intValue());
});
log.info("아직 최종 데이터를 전달 받지는 않았지만, 다른작업 수행가능");
/*메인 스레드가 끝나는것을 방지하기 위한 코드*/
Assert.assertNull(completableFuture.join());
}
public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)
각기 다른 소요시간이 걸리는 비동기 메서드가 전부 완료되었을 때 실행되는 allOf()도 있습니다.
@Test
public void test(){
CompletableFuture<Integer> temp = memberService.getMemberIdAsync("철수");
CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {
log.info("future-1");
return (Integer)1;
});
CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {
log.info("future-2");
return (Integer)2;
});
CompletableFuture completableFuture3 = CompletableFuture.supplyAsync(() -> {
log.info("future-3");
return (Integer)3;
});
List<CompletableFuture> futures = Arrays.asList(completableFuture1,
completableFuture2,
completableFuture3);
CompletableFuture.allOf(completableFuture1, completableFuture2, completableFuture3)
.thenAccept(s -> {
List<Object> result = futures.stream()
.map(pageContentFuture -> pageContentFuture.join())
.collect(Collectors.toList());
log.info(result.toString());
});
/*메인 스레드가 끝나는것을 방지하기 위한 코드*/
Assert.assertEquals(1, temp.join().intValue());
}
간단하게 CompletableFuture의 사용법에 대해서 정리해 보았습니다.
아직 간단하게 사용한 경험밖에 없지만, 능숙하게 사용하게 된다면 유용한 기능일 것 같습니다.
동기, 비동기, 블로킹, 논블로킹에 대해서 좀더 공부해야겠다는 생각이 들었습니다...ㅠ
부족한 포스팅 봐주셔서 감사합니다. 언제나 지적은 감사하게 받겠습니다!
참고 : www.baeldung.com/java-completablefuture
docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html
github : github.com/RATSENO/CompletableFuture-Test
'DEV > JAVA' 카테고리의 다른 글
두개의 List에서 변경된 항목 필터링 (0) | 2021.05.11 |
---|---|
두개의 List에서 삭제된 항목, 추가된 항목 필터링 (0) | 2021.05.11 |
[Lombok]"is"prefix가 붙은 boolean, Boolean (2) | 2021.03.16 |
CompletableFuture<T> -1 (0) | 2021.03.14 |
[JAVA]TreeSet (0) | 2020.02.05 |