Для чего нужен интерфейс Callable в Java?

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

Ответ

Интерфейс Callable<V> представляет асинхронную задачу, которая возвращает результат и может генерировать проверяемые исключения. Он является более функциональной альтернативой интерфейсу Runnable для использования с фреймворком ExecutorService.

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

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

import java.util.concurrent.*;

public class CallableExample {
    public static void main(String[] args) throws Exception {
        // Задача, которая возвращает результат после задержки
        Callable<String> task = () -> {
            Thread.sleep(2000); // Имитация долгой операции
            return "Результат вычисления из потока: " + Thread.currentThread().getName();
        };

        ExecutorService executor = Executors.newFixedThreadPool(2);
        Future<String> future = executor.submit(task); // Неблокирующий вызов

        System.out.println("Делаем что-то ещё в основном потоке...");

        // get() блокирует поток до получения результата
        String result = future.get();
        System.out.println(result); // Результат вычисления из потока: pool-1-thread-1

        executor.shutdown();
    }
}

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