Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 函数apply for CompletableFutures中引发异常_Java_Completable Future - Fatal编程技术网

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