Java의 Future에 대해 알아보자
포스트
취소

Java의 Future에 대해 알아보자

Future란?

Java에서 Future는 비동기 계산의 아직 계산되지 않은 결과를 표현하는 인터페이스입니다. Future의 기본 개념과 사용 방법, 장단점, 그리고 활용 상황에 대해 알아보겠습니다.

Future의 주요 메소드

Future 인터페이스에는 다음과 같은 주요 메소드들이 있습니다.

  • get(): 연산의 결과를 반환합니다. 만약 연산이 아직 완료되지 않았다면, 완료될 때까지 기다립니다. 이 메소드는 Future가 가지는 제네릭 타입의 객체를 반환합니다.
  • get(long timeout, TimeUnit unit): 지정한 시간 동안만 결과를 기다리고, 그 시간이 지나면 TimeoutException을 던집니다. 이 메소드는 시간이 지나면 TimeoutException을 던지며, 그 전에 작업이 완료되면 그 결과를 반환합니다.
  • isDone(): 연산이 완료되었는지의 여부를 반환합니다. 작업이 완료되었다면 true, 그렇지 않다면 false를 반환합니다.
  • cancel(boolean mayInterruptIfRunning): 연산을 취소합니다. 매개 변수는 작업이 진행 중일 때 중단해도 되는지를 결정합니다.
  • isCancelled(): 작업이 취소되었는지의 여부를 반환합니다. 작업이 취소되었다면 true, 그렇지 않다면 false를 반환합니다.

Future 사용 예제

예제 1: Future 생성 및 사용

1
2
3
4
5
6
7
8
9
10
11
12
Callable<Integer> task = () -> {
    Thread.sleep(1000);  // 1초동안 대기
    return 123;  // 결과 반환
};

FutureTask<Integer> future = new FutureTask<>(task);
new Thread(future).start();  // Future 작업 실행

// 다른 작업 ...

Integer result = future.get();  // 결과가 준비될 때까지 Blocking
System.out.println("Result: " + result);

예제 2: ExecutorServiceFuture를 이용해 비동기 작업을 실행하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// ExecutorService 생성
ExecutorService executor = Executors.newFixedThreadPool(10);

// 비동기 작업 제출
// ExecutorService의 submit 메소드는 Callable이나 Runnable 객체를 인수로 받아서 비동기적으로 실행하며, 결과를 Future 객체로 반환합니다.
Future<Integer> future = executor.submit(() -> {
    // 긴 작업 수행
    Thread.sleep(1000);
    return 123;
});

// 다른 작업 수행...

// 결과 가져오기
try {
    Integer result = future.get();  // 결과를 가져옵니다. 필요한 경우에만 호출합니다.
    System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
    // 예외 처리
}

// ExecutorService 종료
executor.shutdown();

예제3: Future에서 결과 가져오기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Integer> future = executorService.submit(() -> {
    Thread.sleep(2000);  // 임의의 긴 작업 수행
    return 10;
});

try {
    Integer result = future.get();  // 결과가 준비될 때까지 블로킹됩니다.
    System.out.println(result);     // 10
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
} finally {
    executorService.shutdown();
}

예제 4: Future에서 타임아웃 설정하여 결과 가져오기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Integer> future = executorService.submit(() -> {
    Thread.sleep(3000);  // 임의의 긴 작업 수행
    return 10;
});

try {
    Integer result = future.get(2, TimeUnit.SECONDS);  // 2초 후에 TimeoutException 발생
    System.out.println(result);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
    e.printStackTrace();
} finally {
    executorService.shutdown();
}

예제 5: Future 작업 취소하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Integer> future = executorService.submit(() -> {
    Thread.sleep(3000);  // 임의의 긴 작업 수행
    return 10;
});

future.cancel(true);  // 작업 취소. 작업이 진행 중이라도 중단합니다.

try {
    Integer result = future.get();  // CancellationException 발생
    System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
} finally {
    executorService.shutdown();
}

Future의 장단점과 활용 상황

Java의 Future 인터페이스는 비동기 작업의 결과를 추상화하고 관리하는데 매우 유용한 도구입니다. 하지만 Future는 모든 상황에 적합한 도구는 아닙니다. 그렇기 때문에 Future의 장단점과 이를 활용하는 적절한 상황에 대해 이해하는 것이 중요합니다.

장점

  • 비동기 작업의 결과를 쉽게 관리할 수 있습니다.
  • 작업 완료를 기다릴 필요 없이, 결과가 필요할 때 가져올 수 있습니다.
  • isDone() 메소드를 통해 작업 완료를 확인할 수 있습니다.

단점

  • 작업 완료 알림의 부재: Future는 작업이 완료되었는지 알려주는 메소드(isDone())를 제공하지만, 이 메소드는 polling 방식으로 작동합니다. 즉, 계속해서 메소드를 호출하여 작업 완료 여부를 확인해야 합니다.
  • 연산 결과를 가져올 때 블로킹됩니다: get() 메소드를 호출하면 결과가 준비될 때까지 현재 스레드가 블로킹됩니다. 이는 get(long timeout, TimeUnit unit) 메소드로 일부 해결할 수 있지만, 완벽한 해결책은 아닙니다.

활용 상황

Future는 비동기 작업의 결과를 관리하고, 그 결과를 필요로 하는 시점에서 쉽게 가져올 수 있어야 하는 경우에 사용됩니다. 하지만 작업 완료 알림이 필요하거나, 비동기 작업 간의 종속성을 관리해야 하는 경우에는 Java 8에서 도입된 CompletableFuture를 사용하는 것이 더 적절합니다. CompletableFutureFuture의 단점을 보완하며, 작업 완료 알림, 작업 체이닝, 예외 처리 등의 추가 기능을 제공합니다

결론

Java의 Future는 비동기 작업의 결과를 처리하는 강력한 도구입니다. 하지만 Future만으로는 작업이 완료될 때까지 블로킹되거나, 작업의 완료를 주기적으로 폴링해야 하는 등의 단점이 있습니다. 이러한 문제를 해결하기 위해 Java 8에서는 CompletableFuture가 도입되었으며, 이는 Future의 기능을 향상시킨 버전입니다. CompletableFutureFuture의 단점을 극복하고, 비동기 작업의 완료 알림이나 종속성 관리와 같은 추가적인 기능을 제공합니다.

그럼에도 불구하고, Future는 여전히 유용하며, 병렬 프로그래밍을 할 때 알아두면 도움이 되는 개념입니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

Java의 함수형 인터페이스와 람다에 대해 알아보자

Linux에서 그룹 및 계정 관리하기

Comments powered by Disqus.