Future

Future<V> — дескриптор одного асинхронного вычисления. Его возвращает ExecutorService.submit.

ExecutorService pool = Executors.newFixedThreadPool(4);
try {
    Future<Integer> future = pool.submit(this::calculate);
    Integer value = future.get(500, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
    // deadline исчерпан
} finally {
    pool.shutdown();
}

Контракт методов

МетодРезультат
get()ждет результат
get(timeout, unit)ждет до timeout
isDone()завершено результатом, ошибкой или отменой
cancel(mayInterruptIfRunning)пытается отменить
isCancelled()успешно отменено

get() может завершиться:

  • значением;
  • ExecutionException, где getCause() — ошибка задачи;
  • CancellationException;
  • InterruptedException у ожидающего потока;
  • TimeoutException у timed-варианта.

Успешное завершение get() создает happens-before от действий задачи к читающему результат потоку.

Отмена

cancel(true) только пытается прервать выполняющий поток. Задача должна поддерживать interrupt; внешний I/O может требовать отдельной отмены. cancel(false) не прерывает уже запущенную задачу.

Проверка isDone() перед get() обычно не нужна и создает polling. Лучше bounded get, callback-абстракция или композиция.

Обычный Future почти не умеет связывать задачи. Для thenApply, объединения и обработки ошибки нужен CompletableFuture.

На собеседовании

  • Означает ли isDone() успешный результат? Нет, это также ошибка или отмена.
  • Гарантирует ли cancel(true) остановку? Нет.
  • Где лежит ошибка Callable? В cause объекта ExecutionException.
  • Что происходит при timeout? Ожидание прекращается, задача продолжает работать, если ее отдельно не отменили.
  • Какая гарантия памяти у get()? Действия задачи видимы после получения результата.