Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что возвращает Callable
Callable — это функциональный интерфейс в Java, который в отличие от Runnable может возвращать результат и выбрасывать проверяемые исключения. Он используется в многопоточных приложениях для выполнения асинхронных задач с получением результата.
Основная сигнатура
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
Генерический параметр V указывает тип возвращаемого значения. Это может быть:
- Примитивный тип (через обёртку): Integer, Long, Double
- Объектный тип: String, List, Custom класс
- Void, если результат не нужен
Возвращаемое значение
Callable возвращает объект типа V, который оборачивается в Future при передаче в ExecutorService:
Callable<String> task = () -> {
Thread.sleep(1000);
return "Результат вычисления";
};
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<String> future = executor.submit(task);
// Получение результата (блокирующий вызов)
String result = future.get(); // "Результат вычисления"
Различие от Runnable
| Параметр | Callable<V> | Runnable |
|---|---|---|
| Возвращаемое значение | V | void |
| Исключение | throws Exception | не выбрасывает |
| Использование | Future<?> submit(Callable) | void execute(Runnable) |
Практические примеры
1. Простой Callable с числовым результатом
Callable<Integer> fibonacci = () -> {
int a = 0, b = 1;
for (int i = 0; i < 10; i++) {
int temp = a + b;
a = b;
b = temp;
}
return b;
};
ExecutorService service = Executors.newSingleThreadExecutor();
Future<Integer> future = service.submit(fibonacci);
try {
Integer result = future.get();
System.out.println("Результат: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
2. Callable с работой с БД
Callable<List<User>> fetchUsers = () -> {
// Имитация долгого запроса к БД
Thread.sleep(2000);
return Arrays.asList(
new User(1, "Alice"),
new User(2, "Bob")
);
};
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<List<User>> future = executor.submit(fetchUsers);
// Можем проверить готовность результата
if (future.isDone()) {
List<User> users = future.get();
}
3. Callable с обработкой исключений
Callable<Double> divide = () -> {
int dividend = 10;
int divisor = 0;
if (divisor == 0) {
throw new IllegalArgumentException("Делитель не может быть нулём");
}
return (double) dividend / divisor;
};
Future<Double> future = executor.submit(divide);
try {
Double result = future.get();
} catch (ExecutionException e) {
// Исключение из Callable обёрнуто в ExecutionException
Throwable cause = e.getCause();
System.out.println("Ошибка: " + cause.getMessage());
}
Получение результата через Future
Future предоставляет несколько способов получить результат:
Future<String> future = executor.submit(callable);
// 1. Получить с ожиданием (блокирует, пока задача не завершится)
String result = future.get();
// 2. Получить с таймаутом (если превышен, выбросит TimeoutException)
String result = future.get(5, TimeUnit.SECONDS);
// 3. Проверить готовность без блокировки
if (future.isDone()) {
String result = future.get();
}
// 4. Отменить задачу (если она ещё не выполняется)
future.cancel(true);
CompletableFuture (современный подход)
Для более удобной работы с асинхронными результатами используется CompletableFuture:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return "Результат";
});
future.thenAccept(result -> System.out.println("Получено: " + result));
Итоги
- Callable возвращает результат типа V через Future
- Может выбрасывать проверяемые исключения
- Идеален для асинхронных задач с получением результата
- Future.get() блокирует текущий поток до готовности результата
- CompletableFuture — более современный и гибкий способ работы с асинхронностью