Метод callable
Метод callable класса Executors преобразует
задачу типа Runnable в задачу типа Callable.
В первый параметр мы передаем объект Runnable, который
нужно преобразовать. Метод возвращает объект Callable,
который при выполнении возвращает null, поскольку
исходный Runnable не возвращает результат.
Также существует перегрузка метода, которая вторым параметром
принимает значение типа T. Это значение будет возвращено
как результат выполнения созданного Callable.
Синтаксис
Executors.callable(Runnable task)
Executors.callable(Runnable task, T result)
Пример
Давайте преобразуем задачу Runnable в 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
{
ExecutorService executor = Executors.newSingleThreadExecutor();
Runnable task = () -> {
System.out.println("Task is running");
};
Callable<Object> callable = Executors.callable(task);
Future<Object> future = executor.submit(callable);
Object res = future.get();
System.out.println("Result: " + res);
executor.shutdown();
}
}
Результат выполнения кода:
"Task is running"
"Result: null"
Пример
Давайте преобразуем Runnable в Callable
с заданным результатом и получим его через Future:
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.newSingleThreadExecutor();
Runnable task = () -> {
System.out.println("Task is running");
};
Callable<String> callable = Executors.callable(task, "abcde");
Future<String> future = executor.submit(callable);
String res = future.get();
System.out.println("Result: " + res);
executor.shutdown();
}
}
Результат выполнения кода:
"Task is running"
"Result: 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(2);
List<Callable<Integer>> callables = new ArrayList<>();
for (int i = 1; i <= 3; i++)
{
int value = i;
Runnable task = () -> {
System.out.println("Task " + value);
};
callables.add(Executors.callable(task, value));
}
List<Future<Integer>> futures = executor.invokeAll(callables);
for (Future<Integer> future : futures)
{
System.out.println("Result: " + future.get());
}
executor.shutdown();
}
}
Результат выполнения кода:
"Task 1"
"Task 2"
"Task 3"
"Result: 1"
"Result: 2"
"Result: 3"
Смотрите также
-
класс
Executors,
который содержит фабричные методы для создания исполнителей -
метод
submit,
который принимает Callable и возвращает Future -
метод
invokeAll,
который выполняет список Callable и возвращает список Future -
метод
newFixedThreadPool,
который создает пул потоков фиксированного размера