Runnable и Callable
Runnable | Callable<V> | |
|---|---|---|
| Метод | void run() | V call() throws Exception |
| Результат | нет | есть |
| Checked exception | объявить нельзя | можно |
| Отправка в executor | execute или submit | submit |
Callable не возвращает Future самостоятельно. Future возвращает ExecutorService.submit, оборачивая результат и ошибку задачи.
ExecutorService pool = Executors.newFixedThreadPool(2);
try {
Runnable audit = () -> writeAudit();
Callable<Integer> count = () -> countRecords();
pool.execute(audit);
Future<Integer> future = pool.submit(count);
System.out.println(future.get());
} finally {
pool.shutdown();
}Исключение из Callable сохраняется в Future и при get() оборачивается в ExecutionException. Исключение из Runnable, переданного через execute, попадает в механизм uncaught exception потока; через submit оно также хранится в Future, поэтому игнорирование возвращенного объекта может скрыть сбой.
См. Объект Future.
На собеседовании
- Возвращает ли
Callable.call()Future? Нет, он возвращаетV; Future создает executor. - Как получить ошибку
Callable? ЧерезExecutionException.getCause()послеget(). - Можно ли отправить
Runnableчерезsubmit? Да, результатом будетFuture<?>. - Что выбрать для fire-and-forget? Обычно
Runnable, но ошибку все равно нужно наблюдать.