public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<String> completableFuture = new CompletableFuture<>(); completableFuture.complete("test"); // 위와 동일한 코드이다. CompletableFuture<String> completableFuture1 = CompletableFuture.completedFuture("test"); // runAsync - 리턴 값이 없는 경우 CompletableFuture<Void> completableFuture2 = CompletableFuture.runAsync(() -> { System.out.println("Hello " + Thread.currentThread().getName()); }); completableFuture2.get(); // 출력 // Hello ForkJoinPool.commonPool-worker-3 // supplyAsync() - 리턴 값이 있는 경우 CompletableFuture<String> completableFuture3 = CompletableFuture.supplyAsync(() -> { return "return Value!!!"; }); System.out.println(completableFuture3.get()); // 출력 // return Value!!! }
public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> { System.out.println("Return : " + Thread.currentThread().getName()); return "return Value!!!"; }).thenApply((s) -> { System.out.println("Then Apply : " + Thread.currentThread().getName()); return s.toUpperCase(); }); // get을 호출하지 않으면 아무일도 일어나지 않는다. String s = completableFuture.get(); System.out.println(s); // 출력 // Return : ForkJoinPool.commonPool-worker-3 // Then Apply : ForkJoinPool.commonPool-worker-3 // RETURN VALUE!!! }
public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> { System.out.println("Return : " + Thread.currentThread().getName()); return "return Value!!!"; }).thenAccept((s) -> { System.out.println("Then Accept : " + Thread.currentThread().getName()); System.out.println("Then Accept To UpperCase : " + s.toUpperCase()); }); completableFuture.get(); // 출력 // Return : ForkJoinPool.commonPool-worker-3 // Then Accept : ForkJoinPool.commonPool-worker-3 // Then Accept To UpperCase : RETURN VALUE!!! }
public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> { System.out.println("Return : " + Thread.currentThread().getName()); return "return Value!!!"; }).thenRun(() -> { // Runnable System.out.println("Then Run : " + Thread.currentThread().getName()); }); completableFuture.get(); // 출력 // Return : ForkJoinPool.commonPReturn : ForkJoinPool.commonPool-worker-3 // Then Run : ForkJoinPool.commonPool-worker-3 }
public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(4); CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> { System.out.println("Return : " + Thread.currentThread().getName()); return "return Value!!!"; } , executorService).thenRun(() -> { // Runnable System.out.println("Then Run : " + Thread.currentThread().getName()); }); completableFuture.get(); executorService.shutdown(); // 출력 // Return : pool-1-thread-1 // Then Run : pool-1-thread-1 }
public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<String> hello = CompletableFuture.supplyAsync(() -> { System.out.println("Hello : " + Thread.currentThread().getName()); return "Hello "; }); // hello.thenCompose(s -> getWorld(s)); CompletableFuture<String> helloWorld = hello.thenCompose(AppForCompletableFuture::getWorld); System.out.println(helloWorld.get()); // 출력 // Hello : ForkJoinPool.commonPool-worker-3 // World : ForkJoinPool.commonPool-worker-5 // Hello World } private static CompletableFuture<String> getWorld(String message) { return CompletableFuture.supplyAsync(() -> { System.out.println("World : " + Thread.currentThread().getName()); return message + " World"; }); }
public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<String> hello = CompletableFuture.supplyAsync(() -> { System.out.println("Hello : " + Thread.currentThread().getName()); return "Hello "; }); CompletableFuture<String> world = CompletableFuture.supplyAsync(() -> { System.out.println("World : " + Thread.currentThread().getName()); return "World"; }); CompletableFuture<String> result = hello.thenCombine(world, (h , w) -> h + " " + w); System.out.println(result.get()); // 출력 // Hello : ForkJoinPool.commonPool-worker-3 // World : ForkJoinPool.commonPool-worker-5 // Hello World }
allOf를 사용하여 작업의 결과를 List로 반환받기
public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<String> hello = CompletableFuture.supplyAsync(() -> { System.out.println("Hello : " + Thread.currentThread().getName()); return "Hello "; }); CompletableFuture<String> world = CompletableFuture.supplyAsync(() -> { System.out.println("World : " + Thread.currentThread().getName()); return "World"; }); List<CompletableFuture> futures = Arrays.asList(hello , world); CompletableFuture[] futuresArray = futures.toArray(new CompletableFuture[futures.size()]); // 결과 타입들이 모두 동일해야한다. CompletableFuture<List<Object>> listCompletableFuture = CompletableFuture.allOf(futuresArray).thenApply(v -> { return futures.stream() .map(CompletableFuture::join) .collect(Collectors.toList()); }); listCompletableFuture.get().forEach(System.out::println); // 출력 // Hello : ForkJoinPool.commonPool-worker-3 // World : ForkJoinPool.commonPool-worker-5 // Hello // World }
public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<String> hello = CompletableFuture.supplyAsync(() -> { System.out.println("Hello : " + Thread.currentThread().getName()); return "Hello "; }); CompletableFuture<String> world = CompletableFuture.supplyAsync(() -> { System.out.println("World : " + Thread.currentThread().getName()); return "World"; }); CompletableFuture<Void> future = CompletableFuture.anyOf(hello, world).thenAccept(System.out::println); future.get(); // 출력 // Hello : ForkJoinPool.commonPool-worker-3 // World : ForkJoinPool.commonPool-worker-5 // Hello }
public static void main(String[] args) throws ExecutionException, InterruptedException { boolean throwError = true; CompletableFuture<String> hello = CompletableFuture.supplyAsync(() -> { if(throwError){ throw new IllegalArgumentException(); } System.out.println("Hello : " + Thread.currentThread().getName()); return "Hello "; }).exceptionally(exceptionType -> { System.out.println("Exception Type : " + exceptionType); return "Error!"; }); System.out.println(hello.get()); // 출력 // Exception Type : java.util.concurrent.CompletionException: java.lang.IllegalArgumentException // Error! }
public static void main(String[] args) throws ExecutionException, InterruptedException { boolean throwError = true; CompletableFuture<String> hello = CompletableFuture.supplyAsync(() -> { if(throwError){ throw new IllegalArgumentException(); } System.out.println("Hello : " + Thread.currentThread().getName()); return "Hello "; }).handle((result , exceptionType) -> { // 첫번째 파라미터 - 정상적인 경우 반환되는 결과 값 // 두번째 파라미터 - 예외 발생시 예외 if(exceptionType != null){ System.out.println("Exception Type : " + exceptionType); return "ERROR !!!"; } return result; }); System.out.println(hello.get()); // 예외 발생 시 "ERROR !!!" 를 반환 // 에외가 발생하지 않았을 시 "Hello" 반환 }
참고
ForkJoinPool (Java Platform SE 8 ) (oracle.com)
CompletableFuture (Java Platform SE 8 ) (oracle.com)
더 자바, Java 8 - 인프런
자바 8에 추가된 기능들은 자바가 제공하는 API는 물론이고 스프링 같은 제 3의 라이브러리 및 프레임워크에서도 널리 사용되고 있습니다. 이 시대의 자바 개발자라면 반드시 알아야 합니다. 이
www.inflearn.com
[JAVA8] CompletableFuture
자바에서 비동기(Asynchronous) 프로그래밍을 가능케하는 인터페이스
CompletableFuture - CompletableFuture (Java Platform SE 8 ) (oracle.com)
비동기로 작업 실행하기
콜백 제공하기
조합하기
allOf를 사용하여 작업의 결과를 List로 반환받기
예외처리
참고
ForkJoinPool (Java Platform SE 8 ) (oracle.com)
CompletableFuture (Java Platform SE 8 ) (oracle.com)
더 자바, Java 8 - 인프런
자바 8에 추가된 기능들은 자바가 제공하는 API는 물론이고 스프링 같은 제 3의 라이브러리 및 프레임워크에서도 널리 사용되고 있습니다. 이 시대의 자바 개발자라면 반드시 알아야 합니다. 이
www.inflearn.com
'기록 > JAVA' 카테고리의 다른 글