Java 函数apply for CompletableFutures中引发异常
我正在创建一些任务,如下所示。这只是为了演示网络调用:Java 函数apply for CompletableFutures中引发异常,java,completable-future,Java,Completable Future,我正在创建一些任务,如下所示。这只是为了演示网络调用: public class RandomTask implements Function<String, String> { private int number; private int waitTime; private boolean throwError; public RandomTask(int number, int waitTime, boolean throwError) {
public class RandomTask implements Function<String, String> {
private int number;
private int waitTime;
private boolean throwError;
public RandomTask(int number, int waitTime, boolean throwError) {
this.number = number;
this.waitTime = waitTime;
this.throwError = throwError;
}
@Override
public String apply(String s) {
System.out.println("Job " + number + " started");
try {
Thread.sleep(waitTime);
if (throwError) {
throw new InterruptedException("Something happened");
}
} catch (InterruptedException e) {
System.out.println("Error " + e.getLocalizedMessage());
}
return "RandomTask " + number + " finished";
}
}
然后我有一个Chain类,在这个类中,我将每个作业的一些任务链接在一起
static CompletableFuture<String> start(ExecutorService executorService) {
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Foo", executorService)
.thenApplyAsync(new RandomTask(3, 100, false), executorService)
.thenApplyAsync(new RandomTask(4, 100, false), executorService);
return future2;
}
然后,我启动2条链,如下所示:
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(Chain1.start(fixedThreadPool), Chain2.start(fixedThreadPool));
try {
combinedFuture.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
这样,两条链条同时启动
现在,我想在一个任务中抛出一个异常,并在调用combinedFuture.get的位置捕获它,以便知道链中哪个任务失败了
问题是,我不能调整函数,因为CompletableFutures对此表示不满。我试过:
@FunctionalInterface
public interface CheckedFunction<T, R> {
R apply(T t) throws InterruptedException;
}
但这不起作用。这是不可能的,或者我如何才能实现我的目标?“这样两条链就同时开始了。”表明您对可完成未来的工作方式有着根本性的错误理解 异步操作在您创建它们时或它们的先决条件可用时立即提交给executor服务。因此,对于没有依赖项的SupplySync,异步操作将在SupplySync调用中启动 总之,类似CompletableFuture.allOfjob1、job2.get这样的构造是根据两个作业创建一个新阶段并等待其完成,因此最终结果只是等待两个作业的完成。它不会启动工作。他们已经在运行了。等待完成对完成过程没有影响 将CompletableFuture与允许检查异常的自定义函数类型链接在一起可以如下所示
public static <T,R> CompletableFuture<R> thenApplyAsync(
CompletableFuture<T> f, CheckedFunction<? super T, ? extends R> cf,
Executor e) {
CompletableFuture<R> r = new CompletableFuture<>();
f.whenCompleteAsync((v,t) -> {
try {
if(t != null) r.completeExceptionally(t);
else r.complete(cf.apply(v));
} catch(Throwable t2) {
r.completeExceptionally(t2);
}
}, e);
return r;
}
给定
static CompletableFuture<String> start(ExecutorService executorService) {
CompletableFuture<String> future2 =
thenApplyAsync(thenApplyAsync(
CompletableFuture.supplyAsync(() -> "Foo", executorService),
new RandomTask(3, 100, false), executorService),
new RandomTask(4, 100, false), executorService);
return future2;
}
public class RandomTask implements CheckedFunction<String, String> {
private int number, waitTime;
private boolean throwError;
public RandomTask(int number, int waitTime, boolean throwError) {
this.number = number;
this.waitTime = waitTime;
this.throwError = throwError;
}
@Override
public String apply(String s) throws InterruptedException {
System.out.println("Job " + number + " started");
Thread.sleep(waitTime);
if (throwError) {
throw new InterruptedException("Something happened in "+number);
}
return "RandomTask " + number + " finished";
}
}
CompletableFuture.allOf(Chain1.start(fixedThreadPool), Chain2.start(fixedThreadPool))
.join();