Runnable과 Callable의 차이: https://www.notion.so/seolnavy/Runnable-Callable-dae409f85a054578a66dfc88f6f01573


Future

public interface Future<V> {
	boolean cancel(boolean mayInterruptIfRunning);

	boolean isCancelled();
	boolean isDone();

	V get() throws InterruptedException, ExecutionException;
	V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

Future 코드 예시

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class FutureExample {

	/**
	 * 제곱을 계산하는 Callable 객체를 생성한다.
	 */
	public Callable<Long> calSquare(final long value) {
//		final Callable<Long> callable = new Callable<Long>() {
//			@Override
//			public Long call() throws Exception {
//				final Long returnValue = value * value;
//				TimeUnit.SECONDS.sleep(1);
//				System.out.println(value + "의 제곱근은 " + returnValue);
//				return returnValue;
//			}
//		};
//		return callable;
		return () -> {
			final Long returnValue = value * value;
			TimeUnit.SECONDS.sleep(1);
			System.out.println(value + "의 제곱근은 " + returnValue);
			return returnValue;
		};
	}

	public void executeTest() {
		// 스레드풀을 생성한다. 고정 스레드 풀을 이용하였다.
		final ExecutorService servicePool = Executors.newFixedThreadPool(4);

		// Callable 객체를 생성한 후, 스레드 풀에 등록한다.
		// 등록된 스레드에 대해 Future 객체를 리턴받는다.
		final List<Long> sampleDataList = Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L);

    /*
     * 비동기 호출
     */
		final List<Future<Long>> futureList = new ArrayList<>();
		for (final Long sampleData : sampleDataList) {
			final Callable<Long> callable = calSquare(sampleData);
			final Future<Long> future = servicePool.submit(callable); // 비동기 실행
			futureList.add(future); // 결과처리를 위해 list에 담는다.(여기서 get()을 호출하면 결과응답까지 기다린다(block된다). list에 담아놓고 나중에 꺼낸다)
		}

    /*
     * 비동기 호출결과 get
     */
		Long sumValue = 0L;
		for (final Future<Long> future : futureList) {
			try {
				// 결과를 읽어 들일 때까지 대기한다.
				// 대기하는 동안, 스레드가 계산을 하고 값을 리턴한다.
				sumValue += future.get();
			} catch (final InterruptedException | ExecutionException e) {
				e.printStackTrace();
			}
		}
		System.out.println("최종 합계 : " + sumValue);

		// 스레드풀 종료
		servicePool.shutdown();
	}

	public static void main(final String[] args) {
		final FutureExample futureExample = new FutureExample();
		futureExample.executeTest();
	}
}

Runnable과 Callable

Future 정리