Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using Supplier in CompletableFuture yields different result than using lambda

I have created a small example of reading a text file and wrap the call with CompletableFuture.

public class Async {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> result = ReadFileUsingLambda(Paths.get("path/to/file"));
        result.whenComplete((ok, ex) -> {
            if (ex == null) {
                System.out.println(ok);
            } else {
                ex.printStackTrace();
            }
        });
    }

    public static CompletableFuture<String> ReadFileUsingSupplier(Path file) throws Exception {
        return CompletableFuture.supplyAsync(new Supplier<String>() {
            @Override
            public String get() {
                try {
                    return new String(Files.readAllBytes(file));
                } catch (IOException e) {
                    e.printStackTrace();
                    return "test";
                }
            }
        }, ForkJoinPool.commonPool());
    }

    public static CompletableFuture<String> ReadFileUsingLambda(Path file) throws Exception {
        return CompletableFuture.supplyAsync(() -> {
            try {
                return new String(Files.readAllBytes(file));
            } catch (IOException e) {
                e.printStackTrace();
                return "test";
            }
        } , ForkJoinPool.commonPool());
    }
}

This code returns nothing. It executes and "nothing happens", no errors or output. If I call ReadFileUsingSupplier instead of ReadFileUsingLambda then I get the file content printed in the console!

To me this doesn't make sense because a lambda is a shorthand for writing an inline function and it shouldn't change the behaviour but in this example it does apparently.

like image 242
Sul Aga Avatar asked Jul 04 '26 16:07

Sul Aga


1 Answers

I think it's just a matter of execution timing - the lambda may take a little more to execute, allowing the program to exit before you are done reading the file.

Try this:

  • add a Thread.sleep(1000); as the first statement within the try block in ReadFileUsingSupplier and you won't see any output
  • add a Thread.sleep(1000); at the end of your main when using ReadFileUsingLambda and you will see the expected output

To make sure your main doesn't exit before the future is completed, you can call:

result.join();
like image 121
assylias Avatar answered Jul 07 '26 04:07

assylias



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!