简体   繁体   中英

java8 asynchronous method CompletableFuture.runAsync doesn't run

very basic code to run asynchronous method. when I run the following code the runAsync doesn't run. what I'm missing?

the result run only the sync code.

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 ");
        });

    }
}

I expect to get first the "sync commands" then the "async command " but get only the sync message

Your task will run in some other Thread (by default in a Thread from ForkJoinPool ) and you are not waiting for it to finish - the main Thread ends before your async task is executed/submitted. You can call CompletableFuture::join to wait for it to finish and it will block the main Thread until it finishes:

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

or like:

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

cf.join();

It does run, but it runs on another thread and you're not waiting or doing anything with the result. As Javadoc of CompletableFuture.runAsync() says:

Returns a new CompletableFuture that is asynchronously completed by a task running in the ForkJoinPool.commonPool() after it runs the given action.

runAsync() is useful for tasks that don't return anything. If you want a result from it you should use supplyAsync() which returns a CompletableFuture<T> Then you can get the result from it:

// 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);

You need to wait for the async task to be completed by using join, for example:

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 ");
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM