Класс Callable
Класс Callable - это функциональный интерфейс из пакета
java.util.concurrent, который описывает задачу,
способную вернуть результат своей работы и бросить проверяемое
исключение. В отличие от интерфейса Runnable, метод
call возвращает значение типа V, поэтому
Callable удобно использовать, когда из потока нужно
получить результат вычислений. Задачу Callable можно
передать в метод submit исполнителя
ExecutorService, который возвращает объект
Future - через него позже можно забрать результат
вызова метода call.
Синтаксис
@FunctionalInterface
public interface Callable<V>
{
V call() throws Exception;
}
Пример
Давайте создадим задачу Callable, которая возвращает
сумму чисел, и выполним её в отдельном потоке через
ExecutorService:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main
{
public static void main(String[] args) throws Exception
{
Callable<Integer> task = () -> {
int sum = 0;
for (int i = 1; i <= 5; i++) {
sum += i;
}
return sum;
};
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(task);
System.out.println(future.get());
executor.shutdown();
}
}
Результат выполнения кода:
15
Пример
Класс Callable позволяет бросать проверяемые исключения.
Давайте создадим задачу, которая бросает исключение при
некорректном значении:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main
{
public static void main(String[] args) throws Exception
{
Callable<String> task = () -> {
String str = "abcde";
if (str.isEmpty()) {
throw new Exception("String is empty");
}
return str.toUpperCase();
};
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(task);
System.out.println(future.get());
executor.shutdown();
}
}
Результат выполнения кода:
"ABCDE"
Пример
Давайте выполним несколько задач Callable параллельно
и соберём их результаты:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main
{
public static void main(String[] args) throws Exception
{
ExecutorService executor = Executors.newFixedThreadPool(3);
List<Future<Integer>> futures = new ArrayList<>();
for (int i = 1; i <= 3; i++) {
final int n = i;
Callable<Integer> task = () -> n * n;
futures.add(executor.submit(task));
}
for (Future<Integer> future : futures) {
System.out.println(future.get());
}
executor.shutdown();
}
}
Результат выполнения кода:
1
4
9