Executors 2

결과를 리턴하는 Runnable, 비동기로 작업의 결과를 확인하는 Future

Future ExecutorService.submit(Callable task)
Callable을 작업을 인수로 받아 작업을 실행하고, Future로 결과를 조회한다.

Callable
결과를 반환하고 예외를 던질 수 있는 Runnable이다

Future
비동기적으로, 계산의 결과를 나타낸다.

Future.isDone()
계산이 완료되었으면 true를 반환한다.

Future.get()
계산의 결과를 가져온다.

Future.cancel(boolean mayInterruptIfRunning)
작업의 실행을 취소시킨다. 취소가 성공하면 true를 반환한다.
mayInterruptIfRunning은 작업을 실행하는 스레드 중단여부다.
이 메소드 실행후 항상 isDone은 true가 되고, 취소가 성공했을땐 get()함수에서 Exception이 발생한다.

예제

	ExecutorService executorService = Executors.newSingleThreadExecutor();
        // Callable을 통해 스레드 작업 후 결과값을 얻을 수 있다.
        Callable<String> hello = getCallable(2000L, "Hello");

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

        // isDone 작업이 종료되었는지 확인한다
        System.out.println(helloFuture.isDone());
        System.out.println("Started!");

        // 블로킹, 값을 가져올때까지 메인스레드는 대기한다. 
        helloFuture.get();

        // 실행중인 작업을 중단한다. false면 실행중인 작업 마치고 중단, true면 바로 중단
//        helloFuture.cancel(false);
        // 실행도중 cancel이 되면 결과값을 가져올 수 없으므로 Exception이 발생한다.(true, false 모두)
//        helloFuture.get();

        System.out.println("End!");
        System.out.println(helloFuture.isDone());

모든 작업 한번에 처리하기

ExecutorService.invokeAll(Collection tasks) 모든 작업들을 처리한 후 future 목록을 반환한다.

예제

	Callable<String> hello = getCallable(2000L, "Hello");
	Callable<String> java = getCallable(3000L, "Java");
	Callable<String> mango = getCallable(1000L, "Mango");

	System.out.println(LocalDateTime.now());
	// invokeAll은 리스트에 있는 모든 작업이 종료될때까지 기다린다.
	List<Future<String>> futures = executorService.invokeAll(Arrays.asList(hello, java, mango));
	for (Future<String> future : futures) {
	    System.out.println(future.get());
	}
	System.out.println(LocalDateTime.now());

가장 빨리 반환되는 작업의 결과 가져오기

ExecutorService.invokeAny(Collection tasks)
tasks 중 가장 빠르게 반환되는 결과를 가져온다.
*주의 스레드가 하나면 첫번째 결과만 반환된다.

예제

	Callable<String> hello = getCallable(2000L, "Hello");
	Callable<String> java = getCallable(3000L, "Java");
	Callable<String> mango = getCallable(1000L, "Mango");

	// 3개 작업을 동시에 실행하기 위해서 3개의 스레드 사용
	ExecutorService executorsService2 = Executors.newFixedThreadPool(3);

	System.out.println(LocalDateTime.now());
	// invokeAny는 모든 작업중 가장 빨리 종료되는 작업의 결과를 반환한다.
	String any = executorsService2.invokeAny(Arrays.asList(hello, java, mango));
	System.out.println(any); 
	System.out.println(LocalDateTime.now());

예제는 이곳 에서 확인할 수 있다.