ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CompletableFuture
    백기선(인프런 강의)/더 자바, Java 8 2020. 7. 22. 13:10
    반응형

    자바에서 비동기(Asynchronous) 프로그래밍을 가능케하는 인터페이스.

    • Future를 사용해서도 어느정도 가능했지만 하기 힘들 일들이 많았다.

     

    Future로는 하기 어렵던 작업들

    • Future를 외부에서 완료 시킬 수 없다. 취소하거나, get()에 타임아웃을 설정할 수는 있다.
    • 블로킹 코드(get())를 사용하지 않고서는 작업이 끝났을 때 콜백을 실행할 수 없다.
    • 여러 Future를 조합할 수 없다, 예) Event 정보 가져온 다음 Event에 참석하는 회원 목록 가져오기
    • 예외 처리용 API를 제공하지 않는다.

     

    CompletableFuture

     

    비동기로 작업 실행하기

    • 리턴값이 없는 경우: runAsync()
    • 리턴값이 있는 경우: supplyAsync()
    • 원하는 Executor(쓰레드풀)를 사용해서 실행할 수도 있다. (기본은 ForkJoinPool.commonPool())
    public class App {
    	public static void main(String[] args) throws InterruptedException, ExecutionException {
    		ExecutorService executorService = Executors.newFixedThreadPool(4);
    		CompletableFuture<Void> futureThenRun = CompletableFuture.supplyAsync(() -> {
    			System.out.println("Hi ThenRun " + Thread.currentThread().getName());
    			return "Hi ThenRun";
    		}, executorService).thenRun(() -> {
    			System.out.println(Thread.currentThread().getName());
    		});
    		futureThenRun.get();
    		executorService.shutdown();
    	}
    }

    결과

     

    콜백 제공하기

    thenApply(Function)

    • 리턴값을 받아서 다른 값으로 바꾸는 콜백

     

    thenAccept(Consumer)

    • 리턴값을 또 다른 작업을 처리하는 콜백 (리턴없이)

     

    thenRun(Runnable)리턴값

    • 받지 다른 작업을 처리하는 콜백

     

    콜백 자체를 또 다른 쓰레드에서 실행할 수 있다.

    • 내부적으로 ForkJoinPool.commonPool 을 사용하지만 상황에 따라서 다른 쓰레드를 사용할 수 있다.

     

     

    예제

    package kr.co.study;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    
    public class App {
    
    	public static void main(String[] args) throws InterruptedException, ExecutionException {
    		// 리턴타입이 없는경우
    		CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
    			System.out.println("Hello " + Thread.currentThread().getName());
    		});
    		future.get();
    		System.out.println("=====================================");
    
    		// 리턴타입이 있는경우
    		CompletableFuture<String> returnFuture = CompletableFuture.supplyAsync(() -> {
    			System.out.println("Hello returnCheck " + Thread.currentThread().getName());
    			return "Hi returnCheck";
    		});
    		System.out.println(returnFuture.get());
    		System.out.println("=====================================");
    
    		// 리턴타입이 있는경우(thenApply 사용)
    		CompletableFuture<String> futureThenApply = CompletableFuture.supplyAsync(() -> {
    			System.out.println("Hi ThenApply " + Thread.currentThread().getName());
    			return "Hi ThenApply ";
    		}).thenApply((s) -> {
    			System.out.println(Thread.currentThread().getName());
    			return s.toUpperCase();
    		});
    		System.out.println(futureThenApply.get());
    		System.out.println("=====================================");
    
    		// 리턴값을 받아서 다른 값으로 바꾸는 콜백(thenAccept 사용)
    		CompletableFuture<Void> futureThenAccept = CompletableFuture.supplyAsync(() -> {
    			System.out.println("Hi ThenAccept " + Thread.currentThread().getName());
    			return "Hi ThenAccept";
    		}).thenAccept((s) -> {
    			System.out.println(Thread.currentThread().getName());
    			System.out.println(s.toUpperCase());
    		});
    		System.out.println("=====================================");
    
    		// 리턴타입이 있는경우(thenAccept 사용)
    		CompletableFuture<Void> futureThenRun = CompletableFuture.supplyAsync(() -> {
    			System.out.println("Hi ThenRun " + Thread.currentThread().getName());
    			return "Hi ThenRun";
    		}).thenRun(() -> {
    			System.out.println(Thread.currentThread().getName());
    		});
    		System.out.println("=====================================");
    
    	}
    }

    결과

    반응형

    '백기선(인프런 강의) > 더 자바, Java 8' 카테고리의 다른 글

    애노테이션의 변화  (0) 2020.07.24
    CompletableFuture 2  (0) 2020.07.23
    Callable과 Future  (0) 2020.07.20
    Executors  (0) 2020.07.16
    자바 Concurrent 프로그래밍 소개  (0) 2020.07.16
Designed by Tistory.