Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.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 completableFuture.CompleteExceptionly()与引发异常之间的区别_Java_Multithreading_Completable Future - Fatal编程技术网

Java completableFuture.CompleteExceptionly()与引发异常之间的区别

Java completableFuture.CompleteExceptionly()与引发异常之间的区别,java,multithreading,completable-future,Java,Multithreading,Completable Future,当我异常地使用completeet时,我无法阻止运行它的线程在它之后继续运行代码。 如果我在异常完成后抛出异常,.get()将捕获该异常,而不是我在异常完成后抛出的异常 if(doProcessException){ log.error("before Completeexceptionally called"); cf.completeExceptionally(new StepException("Dummy exception

当我异常地使用
completeet
时,我无法阻止运行它的线程在它之后继续运行代码。 如果我在异常完成后抛出异常,.get()将捕获该异常,而不是我在异常完成后抛出的异常

if(doProcessException){
        log.error("before Completeexceptionally called");
        cf.completeExceptionally(new StepException("Dummy exception thrown in doProcess",new IOException("dummy IOExcetion in dummy step"), this.getStepName()));
        throw new RuntimeException();
    }
logs.error("After Completeexceptionally called, why am i running?);
如果我异常地完成了,我不希望代码段中的log.error运行

我希望使用
CompletableFuture
运行该逻辑的线程停止

如果我运行上面的代码,将捕获空运行时异常,而不是我放入
completeeexceptionaly()中的详细异常

如果我甚至删除了
completeeexceptionaly()
,那么我在.get()上也会遇到同样的问题

如果是这样,如果我必须处理.get()异常,
completableFuture.exception(()->{})
的目的是什么

我在
completeeException
中所写的内容可以放在我的
completableFuture.get()
的catch部分,然后我只在runnable中抛出一个异常,从而停止该线程的任何进一步进程

我可能用错了

编辑: 我会按照评论中的要求提供更多细节

我的情况有点复杂,所以我会尽量简化

我有两个层,一个基础结构层,它使用
.thencomposasync()
方法创建一个完整的未来链

创建链后,我使用
.get(timeout)
阻止我的infra代码,并给整个链超时以完成作业

这个
.get()
迫使我像这样尝试捕捉

try {
        finalEnrichmentResponse = completableFuture.get(enrichmentTimeoutMs, TimeUnit.MILLISECONDS);
        endResult = finalEnrichmentResponse.getData();
    } catch (InterruptedException e) {
        enrichmentException(enrichmentResponse.getData(), finalEnrichmentResponse, e, "Step chain threw InterruptedException");
    } catch (ExecutionException e) {
        enrichmentException(enrichmentResponse.getData(), finalEnrichmentResponse, e, "Step chain threw ExecutionException...");
    } catch (TimeoutException e) {
        enrichmentException(enrichmentResponse.getData(), finalEnrichmentResponse, e, "Step chain exceeded the configured timeout: " + enrichmentTimeoutMs + "ms");
    }
据我所知,这些捕获是如果comletableFuture抛出了一个例外。而且没有一个
.excellected()
方法,我认为这是安全的

现在我的问题从我的逻辑层开始,在那里,我为链中的每个“步骤”使用了另一个完全的未来

我的链中的步骤是同步工作的

所以基本上我调用了这个步骤的方法,它返回一个completableFuture并执行一个类似这样的
get()

stepResponse = doProcessCf.get();

                } catch (EntityStoppedException e) {
                   //specific handling
                } catch (InterruptedException e) {
                   //specific handling
                } catch (Exception e) {
                   //specific handling
                }
这里我不给出一个超时,因为如果实际逻辑超时,它已经由超时链计算出来了

我知道这种架构可能不好,但这是我第一次尝试completable futures

因为我在逻辑层中没有一个
completableFuture.excellective
,如果对逻辑程序员
completeeexcellective()
,那么catch会处理它

这可能是我的问题?我需要为这个完整的未来添加一个
。异常(()->{})

无论如何,问题是如果我从步骤中得到的ComePlableFuture在代码中的某个地方执行
CompleteExceptionly()
,那么他在那之后编写的其余代码仍在运行

因此,也许解决方案只是告诉step程序员以一种方式管理他的代码,如果他决定
completeeexceptionaly()
他就不能让任何代码在其之后运行?单点返回指令

为简单起见,我们可以假设链只有一个步骤

我认为可以用更优雅的方式来做


提前感谢…

一个完整的未来的关键在于它在不同的线程中执行(由执行者提供)。在此线程中引发RuntimeException对其他线程没有影响。如果要停止后台任务,并调用其方法。代码中有另一个线程正在运行,只有在那里我才知道是否需要关闭它。。因为complete不会为它运行的线程执行此操作。代码将一直运行到最后,在创建completableFuture的线程中,他将执行我提供的异常(()->{})。因此,即使我在异常部分中关闭了它,代码仍然会继续更快,然后我将能够关闭它(假设它同时发生)。我错了吗?如果你能提供一个你的场景的详细描述,这将使某人更容易正确地回答你的问题。但一般来说,在例外情况下,完成一个
CompletableFuture
允许所有相关阶段对故障做出适当的反应;如果您在没有完成将来的操作的情况下抛出异常,那么依赖阶段将永远不会收到失败的通知。这感觉就像-似乎您正在使用CompleteException来完成它不可能完成的事情。你想完成什么?是否希望异步任务自行取消?是否希望一个位于CompletableFuture之外的线程停止CompletableFuture?你想停止一个完整的未来,然后立即终止正在等待它的方法吗?我编辑了这个问题,以包含更多的信息,通过这样做,我想我可能已经找到了解决方案,但我仍然希望听到你的意见!完全未来的关键在于它在不同的线程中执行(由执行器提供)。在此线程中引发RuntimeException对其他线程没有影响。如果要停止后台任务,并调用其方法。代码中有另一个线程正在运行,只有在那里我才知道是否需要关闭它。。因为complete不会为它运行的线程执行此操作。代码将一直运行到最后,在创建completableFuture的线程中,他将执行我提供的异常(()->{})。因此,即使我在异常部分中关闭了它,代码仍然会继续更快,然后我将能够关闭它(假设它同时发生)。我错了吗?如果你能提供一个你的场景的详细描述,这将使某人更容易正确地回答你的问题。但一般来说,完成一个
CompletableFuture
异常地允许所有相关阶段对故障做出反应