[Java 8] Callable과 Future

홍정완·2022년 6월 22일
0

Java

목록 보기
12/25
post-thumbnail

Callable

  • Runnable과 유사, 작업의 결과를 받을 수 있다.

    • Callable 작업을 수행하기 위해 submit 메서드의 인자로 넘겨준다.
    • submit 메서드는 Future를 반환한다.

Future

  • 비동기적인 작업의 현재 상태를 조회하거나 결과를 가져올 수 있다.

    • Callable이 반환하는 값을 Future의 get 메서드를 통해 얻을 수 있다.



get()


import java.util.concurrent.*;

public class App {

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        ExecutorService executorService = Executors.newSingleThreadExecutor();

        Callable<String> hello = () -> {
            Thread.sleep(3000);

            return "hello";
        };

        Future<String> future = executorService.submit(hello);
        System.out.println(future.get()); // 3초 뒤 hello 출력

        executorService.shutdown();
    }
}



❗ 주의


	Future<String> future = executorService.submit(hello);

    System.out.println("Start");
    System.out.println(future.get());
    System.out.println("End");

    executorService.shutdown();

  • get 메서드를 만나는 순간 Callable의 결과를 가져올 때까지 기다린다.

    • 일종의 Blocking call



isDone(), 작업 상태 확인


    Future<String> future = executorService.submit(hello);

    System.out.println("작업 상태 확인 : " + future.isDone());
    System.out.println("Start");

    System.out.println(future.get());

    System.out.println("작업 상태 확인 : " + future.isDone());
    System.out.println("End");

    executorService.shutdown();



cancel(), 작업 취소


	Future<String> future = executorService.submit(hello);

    System.out.println("Start");
    future.cancel(false);

    System.out.println(future.isDone()); // true, false 둘 다 true 반환
    System.out.println(future.get());
    System.out.println("End");

  • cancel()에 true를 넘겨주면 현재 진행 중인 작업을 인터럽트 하면서 종료

    • false를 넘겨주면 작업 대기
    • true, false 모두 작업의 결과를 get 할 수 없다.

Exception in thread "main" java.util.concurrent.CancellationException




invokeAll(), 여러 작업 동시 실행


	ExecutorService executorService = Executors.newFixedThreadPool(3);

    Callable<String> hong = () -> {
        Thread.sleep(1000);

        return "hong";
    };

    Callable<String> jung = () -> {
        Thread.sleep(2000);

        return "jung";
    };

    Callable<String> wan = () -> {
        Thread.sleep(3000);

        return "wan";
    };

    List<Future<String>> futures = executorService.invokeAll(Arrays.asList(hong, jung, wan));

    for (Future<String> future : futures) {
        System.out.println(future.get());
    }

  • invokeAll 메서드에 여러 작업들을 컬렉션으로 넘겨줄 수 있다.

    • invokeAll을 사용하면 모든 작업이 종료할 때까지 먼저 끝난 작업이 기다린다.



invokeAny(), 여러 작업 중에 하나라도 먼저 응답오면 끝내기


	String answer = executorService.invokeAny(Arrays.asList(hong, jung, wan));

    System.out.println(answer);

  • 작업의 반환 값을 Future로 감싸지 않고 바로 반환

  • 3개의 서버 존재 -> 동일 파일 존재 -> 파일 요청 시, 빠른 곳에서 하나만 받아도 됨

    • 위의 경우에서 사용
profile
습관이 전부다.

0개의 댓글