Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Callable в Java
Callable — это функциональный интерфейс из пакета java.util.concurrent, который представляет задачу, способную вернуть результат и выбросить проверяемое исключение. Это улучшенная версия интерфейса Runnable, который не возвращает значение.
Основные различия от Runnable
// Runnable не возвращает результат
interface Runnable {
void run();
}
// Callable возвращает результат типа V
interface Callable<V> {
V call() throws Exception;
}
Зачем нужен Callable
1. Получение результата из потока
В многопоточности часто нужно выполнить задачу в отдельном потоке и получить результат. Callable с ExecutorService позволяет это делать:
ExecutorService executor = Executors.newFixedThreadPool(2);
Callable<Integer> task = () -> {
Thread.sleep(2000);
return 42;
};
Future<Integer> future = executor.submit(task);
Integer result = future.get(); // Блокирует до получения результата
System.out.println("Результат: " + result);
2. Обработка исключений
В отличие от Runnable, Callable может выбросить проверяемое исключение (throws Exception), что удобнее:
Callable<String> fileReader = () -> {
// Может выбросить IOException, которое будет обработано
return new String(Files.readAllBytes(Paths.get("file.txt")));
};
try {
String content = executor.submit(fileReader).get();
} catch (ExecutionException e) {
System.out.println("Ошибка: " + e.getCause());
}
3. Работа с Future
ExecutorService.submit(Callable) возвращает Future объект, который позволяет:
- Проверить, завершена ли задача:
isDone() - Отменить задачу:
cancel() - Получить результат с таймаутом:
get(long timeout, TimeUnit unit)
Future<Integer> future = executor.submit(() -> computeExpensiveValue());
if (!future.isDone()) {
System.out.println("Задача ещё выполняется");
}
try {
Integer result = future.get(5, TimeUnit.SECONDS); // Ждать максимум 5 секунд
} catch (TimeoutException e) {
System.out.println("Задача не завершилась вовремя");
future.cancel(true);
}
Практический пример
ExecutorService executor = Executors.newFixedThreadPool(3);
List<Callable<String>> tasks = Arrays.asList(
() -> "Результат задачи 1",
() -> "Результат задачи 2",
() -> { Thread.sleep(1000); return "Результат задачи 3"; }
);
List<Future<String>> futures = executor.invokeAll(tasks);
for (Future<String> future : futures) {
System.out.println(future.get());
}
executor.shutdown();
Когда использовать
- Нужен результат из фонового потока
- Нужна обработка исключений в потоке
- Нужна возможность отменить задачу
- Нужно установить таймаут на выполнение
Callable — незаменимый инструмент для асинхронного программирования в Java, позволяющий безопасно работать с результатами многопоточных операций.