Вопрос проверяет понимание базовых интерфейсов для выполнения задач в многопоточном коде и различий в их возможностях.
Runnable описывает задачу без возвращаемого результата. Callable может возвращать результат и выбрасывать проверяемые исключения. Runnable используется в простых сценариях. Callable чаще применяют вместе с пулами потоков. Выбор зависит от того, нужен ли результат выполнения.
Runnable и Callable решают одну задачу — описывают код, который должен быть выполнен в другом потоке, но делают это по-разному.
Runnable — функциональный интерфейс для задачи без результата.
Callable — функциональный интерфейс для задачи, возвращающей результат.
Перед перечислением важно отметить: основная разница — в контракте выполнения.
Runnable
метод run()
не возвращает результат
Callable
метод call()
возвращает значение
Runnable
не может бросать checked exception
Callable
может бросать checked exception
Runnable
подходит для fire-and-forget задач
Callable
используется вместе с Future
Callable<Integer> task = () -> 42;
Future<Integer> result = executor.submit(task);
Runnable подходит для простых задач без результата, а Callable — для вычислений, где нужен результат или обработка ошибок.