有没有办法创建一个未启动的CompletableFuture?喜欢 Thread.Builder::unstarted?

问题描述 投票:0回答:1

标题大部分是不言自明的。我正在尝试解决一个问题,但为了做到这一点,我需要

CompletableFuture
才能尝试执行,直到有人开始通过
CompletableFuture::get
或类似的东西运行它。

如果需要,我准备转学到另一个班级,但我想先在这里问一下。有没有办法创建一个未启动的

CompletableFuture
,或者至少不会尝试立即执行自身?

我想正确的术语应该是对

CompletableFuture
的惰性求值。

这是

Thread.Builder::unstarted
的文档。

java lazy-evaluation completable-future
1个回答
0
投票

基于 Baeldung 的代码片段:

public Future<String> calculateAsync() throws InterruptedException {
    CompletableFuture<String> completableFuture = new CompletableFuture<>();

    Executors.newCachedThreadPool().submit(() -> {
        Thread.sleep(500);
        completableFuture.complete("Hello");
        return null;
    });

    return completableFuture;
}

这是我尝试过的:

@Slf4j
@SpringBootApplication
public class springLoader {
    public static final Class<springLoader> CLASS = springLoader.class;
    private ExecutorService threadpool = Executors.newCachedThreadPool();

    public static void main(String[] args) throws JsonProcessingException, InterruptedException, ExecutionException {
        springLoader loader = null;
        try (final var context = SpringApplication.run(CLASS, args)) {
            loader = context.getBean(CLASS);

//            var returned = loader.calculateAsync();
//            var returned = loader.calculateAsyncSupplier();
            var returned = loader.calculateAsyncWithASupplier();
            log.info("printing out stuff");
            log.info("now: {}", System.currentTimeMillis());
//            log.info(returned.get());
            log.info("complete: {}", System.currentTimeMillis());
            var completeFuture = returned.get();
        }finally {
            loader.threadpool.shutdown();
        }
    }

    public Future<String> calculateAsync() throws InterruptedException {
        CompletableFuture<String> completableFuture = new CompletableFuture<>();

        threadpool.submit(() -> {
            log.info("sleeping now: {}", System.currentTimeMillis());
            Thread.sleep(5000);
            log.info("sleeping complete: {}", System.currentTimeMillis());
            completableFuture.complete("Hello");
            return null;
        });

        return completableFuture;
    }

    public Future<String> calculateAsyncWithASupplier() throws InterruptedException {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(()->{
            log.info("sleeping now: {}", System.currentTimeMillis());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            log.info("sleeping complete: {}", System.currentTimeMillis());
            return "Hello";
        });
        return completableFuture;
    }

    public Supplier<CompletableFuture<String>> calculateAsyncSupplier() {
        Supplier<CompletableFuture<String>> asyncSupplier = () -> {
            CompletableFuture<String> completableFuture = new CompletableFuture<>();

            threadpool.submit(() -> {
                log.info("sleeping now: {}", System.currentTimeMillis());
                Thread.sleep(5000);
                log.info("sleeping complete: {}", System.currentTimeMillis());
                completableFuture.complete("Hello");
                return null;
            });

            return completableFuture;
        };
        return asyncSupplier;
    }
}

我做到了:

  1. 将 CompletableFuture 的创建包装在供应商内,这样只有当我真正需要它时,我才会创建 CompletableFuture 并提示它执行任何操作。
  2. CompletableFuture.supplyAsync

如果它有效,它不应该在记录完整之前打印/记录与睡眠相关的任何内容。然后我对返回的 var 进行了注释和取消注释,并比较了输出。

对于 baeldung 的基本案例,它记录了如下内容:

对于1.结果如下:

至于2.,似乎不起作用:

我在 1. 中所做的似乎最接近您想要的,但是有一个供应商包装器可能会妨碍您,因为现在您需要调用 returned.get().get() 来访问 CompletableFuture 返回的任何值。我很想知道您对 ruakh 的答案或 ruakh 自己的答案的实现,所以我会等待这些。

© www.soinside.com 2019 - 2024. All rights reserved.