Looking for java Keywords? Try Ask4Keywords

Java Language Определение асинхронных задач Inline с использованием Lambdas


пример

Хотя хороший дизайн программного обеспечения часто максимизирует повторное использование кода, иногда бывает полезно определить асинхронные задачи, встроенные в ваш код, с помощью выражений лямбда, чтобы максимизировать читаемость кода.

В этом примере мы создадим один класс, который содержит метод main (). Внутри этого метода мы будем использовать выражения Lambda для создания и выполнения экземпляров Callable и Runnable <T>.

AsyncExample3.java

import lombok.extern.java.Log;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

@Log
public class AsyncExample3 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        List<Future<Integer>> futures = new ArrayList<>();
        for(int i = 0; i < 5; i++){
            final int index = i;
            executorService.execute(() -> {
                int timeout = getTimeout();
                log.info(String.format("Runnable %d has been submitted and will sleep for %d seconds", index, timeout));
                try {
                    TimeUnit.SECONDS.sleep(timeout);
                } catch (InterruptedException e) {
                    log.warning(e.getMessage());
                }
                log.info(String.format("Runnable %d has finished sleeping", index));
            });
            Future<Integer> submittedFuture = executorService.submit(() -> {
                int timeout = getTimeout();
                log.info(String.format("Callable %d will begin sleeping", index));
                try {
                    TimeUnit.SECONDS.sleep(timeout);
                } catch (InterruptedException e) {
                    log.warning(e.getMessage());
                }
                log.info(String.format("Callable %d is done sleeping", index));
                return timeout;
            });
            futures.add(submittedFuture);
        }
        executorService.shutdown();
        while(!futures.isEmpty()){
            for(int j = 0; j < futures.size(); j++){
                Future<Integer> f = futures.get(j);
                if(f.isDone()){
                    try {
                        int timeout = f.get();
                        log.info(String.format("A task just completed after sleeping for %d seconds", timeout));
                        futures.remove(f);
                    } catch (InterruptedException | ExecutionException e) {
                        log.warning(e.getMessage());
                    }
                }
            }
        }
    }

    public static int getTimeout(){
        return ThreadLocalRandom.current().nextInt(1, 20);
    }
}

Замечания:

В приведенном выше выводе есть несколько вещей,

  1. Лямбда-выражения имеют доступ к переменным и методам, доступным для области, в которой они определены, но все переменные должны быть окончательными (или фактически окончательными) для использования внутри лямбда-выражения.
  2. Нам не нужно указывать, является ли наше Lambda выражение Callable или Runnable <T> явно, возвращаемый тип автоматически выводится по типу возвращаемого значения.