标题大部分是不言自明的。我正在尝试解决一个问题,但为了做到这一点,我需要
CompletableFuture
才能尝试执行,直到有人开始通过 CompletableFuture::get
或类似的东西运行它。
如果需要,我准备转学到另一个班级,但我想先在这里问一下。有没有办法创建一个未启动的
CompletableFuture
,或者至少不会尝试立即执行自身?
我想正确的术语应该是对
CompletableFuture
的惰性求值。
Thread.Builder::unstarted
的文档。
基于 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;
}
}
我做到了:
如果它有效,它不应该在记录完整之前打印/记录与睡眠相关的任何内容。然后我对返回的 var 进行了注释和取消注释,并比较了输出。
我在 1. 中所做的似乎最接近您想要的,但是有一个供应商包装器可能会妨碍您,因为现在您需要调用 returned.get().get() 来访问 CompletableFuture 返回的任何值。我很想知道您对 ruakh 的答案或 ruakh 自己的答案的实现,所以我会等待这些。