Что такое интерфейс Callable в Java и чем он отличается от Runnable?

«Что такое интерфейс Callable в Java и чем он отличается от Runnable?» — вопрос из категории Java Core, который задают на 23% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Callable<V> — это функциональный интерфейс в Java (java.util.concurrent), представляющий асинхронную задачу, которая возвращает результат типа V и может выбрасывать проверяемое исключение.

Сигнатура метода:

V call() throws Exception;
Ключевые отличия от Runnable: Особенность Runnable Callable<V>
Возвращаемое значение void Тип V
Исключения Не может бросать проверяемые исключения Может бросать Exception
Запуск через ExecutorService execute(Runnable) или submit(Runnable) Только submit(Callable)
Результат Future<?> (всегда null) Future<V> (содержит результат)

Пример создания и выполнения Callable:

import java.util.concurrent.*;

// Задача, возвращающая результат после задержки
Callable<Integer> computeTask = () -> {
    Thread.sleep(2000); // Может бросать InterruptedException
    return 10 * 10; // Возвращаем результат
};

ExecutorService executor = Executors.newSingleThreadExecutor();

// submit() возвращает Future для управления задачей и получения результата
Future<Integer> future = executor.submit(computeTask);

try {
    // get() блокирует поток до завершения задачи и возвращает результат
    Integer result = future.get(); // 100
    System.out.println("Результат: " + result);
} catch (InterruptedException | ExecutionException e) {
    // ExecutionException оборачивает исключение, выброшенное в call()
    e.printStackTrace();
} finally {
    executor.shutdown();
}

Применение: Callable используется, когда задача в отдельном потоке должна вернуть результат или требует обработки проверяемых исключений, например, для вычислений, запросов к БД или внешним API.