В чем разница между Future, FutureTask и CompletableFuture в Java?

«В чем разница между Future, FutureTask и CompletableFuture в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Future — это базовый интерфейс для представления результата асинхронного вычисления. Он предоставляет методы для проверки завершения (isDone()), ожидания результата (get()) и отмены задачи (cancel()). Его главный недостаток — отсутствие механизма обратного вызова (callback), что делает код блокирующим.

FutureTask — это конкретная реализация интерфейса Future, которая также реализует Runnable. Это позволяет выполнить задачу (Callable или Runnable) в отдельном потоке, передав FutureTask в конструктор Thread или исполнителю (Executor).

CompletableFuture (Java 8+) — это расширенная, наиболее мощная реализация Future, которая поддерживает асинхронное программирование без блокировок. Она позволяет:

  • Строить цепочки асинхронных операций.
  • Комбинировать результаты нескольких Future.
  • Явно завершать вычисление (complete(), completeExceptionally()).
  • Регистрировать callback-функции.

Пример использования CompletableFuture:

CompletableFuture.supplyAsync(() -> "Hello")
    .thenApply(s -> s + " World")
    .thenAccept(System.out::println) // Hello World
    .join();

Ключевые отличия:

  • Future: Базовый, блокирующий интерфейс.
  • FutureTask: Конкретная реализация Future + Runnable для запуска задач.
  • CompletableFuture: Богатый API для неблокирующей, композируемой асинхронной обработки.