Пример вызываемого будущего на Java

Одним из преимуществ Java executor framework является то, что мы можем запускать параллельные задачи, которые могут возвращать один результат после обработки задач. Java Concurrency API достигает этого с помощью следующих двух интерфейсов Callable и Future.

В этом уроке мы научимся выполнять задачи Callable(которые возвращают результат типа Future после выполнения) с использованием реализаций ExecutorService в этом простом примере Callable Future.

1. Вызываемые и будущие интерфейсы Java

1.1. Отзывной

В Java concurrency Callable представляет задачу, которая возвращает результат. Исполнители могут запускать вызываемые задачи – параллельно. Начиная с Java 8, это функциональный интерфейс и, следовательно, может использоваться в качестве цели назначения для лямбда-выражения или ссылки на метод.

Интерфейс Callable имеет метод call(). В этом методе мы должны реализовать логику задачи. Интерфейс Callable — это параметризованный интерфейс, то есть мы должны указать тип данных, которые вернет метод call().

@FunctionalInterfacepublic interface Callable<V> {/*** Computes a result, or throws an exception if unable to do so.** @return computed result* @throws Exception if unable to compute a result*/V call() throws Exception;}

2.2 Будущее

Интерфейс Future имеет методы для получения результата, сгенерированного объектом Callable, и управления его состоянием. Он представляет собой результат асинхронного вычисления. Результат может быть получен только с помощью метода get() после завершения вычисления, блокируя его при необходимости до тех пор, пока он не будет готов.

Отмена задачи выполняется методом cancel(). После завершения вычисления его нельзя отменить.

public interface Future<V>{boolean cancel(boolean mayInterruptIfRunning);boolean isCancelled();boolean isDone();V get() throws InterruptedException, ExecutionException;V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;}

2. Пример вызываемого будущего на Java

В этом примере мы выполняем задачу, которая возвращает свое имя после завершения. Мы будем использовать ExecutorService для выполнения этой задачи и вывода ее имени в основном потоке после ее завершения.

Future.get() используется для блокировки выполнения основного потока до тех пор, пока соответствующая задача, отправленная исполнителю, не будет завершена. Он может, опционально, занять период тайм-аута, после которого он разблокируется с помощью TimeOutException.

import java.time.LocalDateTime;import java.util.concurrent.*;public class CallableFutureExample {public static void main(String[] args) throws ExecutionException,InterruptedException, TimeoutException {ExecutorService executor = Executors.newFixedThreadPool(1);Future<String> future = executor.submit(new Work("Demo-Task"));String completedThread = future.get(10, TimeUnit.SECONDS);System.out.println("Thread completed : " + completedThread);}}class Work implements Callable<String> {private final String name;public Work(String name) {this.name = name;}@Overridepublic String call() {System.out.println("Task [" + name + "] executed on : " + LocalDateTime.now().toString());return name;}}

Вывод программы.

Task [Demo-Task] executed on : 2022-08-07T15:57:33.372000500Thread completed : Demo-Task 

Здесь мы отправили объект Callable для выполнения в executor с помощью метода submit(). Этот метод получает объект Callable в качестве параметра и возвращает объект Future, который мы можем использовать с двумя основными целями:

  1. Мы можем контролировать статус задачи – мы можем отменить задачу и проверить, завершилась ли она. Для этого мы можем использовать метод isDone(), чтобы проверить, завершились ли задачи.
  2. Мы можем получить результат, возвращаемый методом call(). Для этой цели мы использовали метод get(). Этот метод ждет, пока объект Callable не завершит выполнение метода call() и не вернет свой результат.

    Если поток прерывается, пока метод get() ожидает результат, он выдает исключение InterruptedException. Если метод call() выдает исключение, этот метод выдает исключение ExecutionException.

3. Заключение

В этом уроке мы изучили основы интерфейсов Callable и Future и то, как выполнять вызываемые задачи с помощью ExecutorService. Мы научились контролировать выполнение с помощью методов isDone(), cancel() и get().

Прокрутить вверх