java8 асинхронный метод CompletableFuture.runAsync не запускается - PullRequest
0 голосов
/ 06 ноября 2019

очень простой код для запуска асинхронного метода. когда я запускаю следующий код, runAsync не запускается. чего мне не хватает?

в результате запускается только код синхронизации.

public class Main {

    public static void main(String[] args) {
        runAsync("run async command ans wait 10000");

        System.out.println("sync commands ");
    }

    public static void runAsync(String inputStr) {

       CompletableFuture.runAsync(() -> {
            List<String> strings = Arrays.asList(inputStr.split(" "));
            int sleep = Integer.parseInt(strings.get(strings.size() - 1));
            try {
                sleep(sleep);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("async command ");
        });

    }
}

Я ожидаю сначала получить "команды синхронизации", а затем "асинхронную команду", но получить только синхронизациюсообщение

Ответы [ 3 ]

1 голос
/ 06 ноября 2019

Ваша задача будет выполняться в каком-то другом Thread (по умолчанию в Thread из ForkJoinPool), и вы не дожидаетесь ее завершения - основная Thread заканчивается до того, как ваша асинхронная задача будет выполнена / отправлена,Вы можете позвонить CompletableFuture::join, чтобы дождаться его завершения, и он заблокирует основной Thread до его завершения:

CompletableFuture.runAsync(() -> {
        List<String> strings = Arrays.asList(inputStr.split(" "));
        int sleep = Integer.parseInt(strings.get(strings.size() - 1));
        try {
            sleep(sleep);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("async command ");
}).join(); //here call the join

или как:

CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
   //...
});

cf.join();
0 голосов
/ 06 ноября 2019

Вам нужно дождаться завершения асинхронной задачи с помощью объединения, например:

public static void main(String[] args) {
    CompletableFuture<Void> future = runAsync("run async command ans wait 10000");
    future.join();
    System.out.println("sync commands ");
}

public static CompletableFuture<Void> runAsync(String inputStr) {
    return CompletableFuture.runAsync(() -> {
        List<String> strings = Arrays.asList(inputStr.split(" "));
        int sleep = Integer.parseInt(strings.get(strings.size() - 1));
        try {
            sleep(sleep);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("async command ");
    });
}
0 голосов
/ 06 ноября 2019

Он работает, но работает в другом потоке, и вы не ждете или ничего не делаете с результатом. Как сказано в Javadoc из CompletableFuture.runAsync():

Возвращает новое CompletableFuture, которое асинхронно завершается задачей, выполняющейся в ForkJoinPool.commonPool () после запуска данного действия.

runAsync() полезно для задач, которые ничего не возвращают. Если вы хотите получить результат, вы должны использовать supplyAsync(), который возвращает CompletableFuture<T> Тогда вы можете получить результат из него:

// Run a task specified by a Supplier object asynchronously
CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {
    @Override
    public String get() {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
        return "Result of the asynchronous computation";
    }
});

// Block and get the result of the Future
String result = future.get();
System.out.println(result);
...