Ответ
CallableRunnable.
Основные области применения:
-
Исполнение в пуле потоков (ExecutorService): Передача задач, требующих возврата результата.
ExecutorService executor = Executors.newFixedThreadPool(2); Callable<Integer> computeTask = () -> { // Долгие вычисления return 42; }; -
Получение результата через Future: Метод
ExecutorService.submit(Callable)возвращаетFuture<V>, который используется для асинхронного получения результата или контроля над задачей.Future<Integer> future = executor.submit(computeTask); // ... делать другую работу ... Integer result = future.get(); // Блокирует поток, пока задача не завершится -
Обработка исключений внутри задачи:
Callable.call()объявляетthrows Exception, что позволяет корректно пробрасывать исключения из потока в вызывающий код.Callable<String> riskyTask = () -> { if (error) throw new IOException("Read failed"); return "Success"; }; // Исключение будет обернуто в ExecutionException при вызове future.get()
Главное отличие от Runnable: Runnable.run() не возвращает значения и не может бросать проверяемые исключения.