如何在ScheduledExecutiorService中抛出新异常



我有以下代码:

public void restart() throws Exception
{
CompletableFuture<?> delayed = new CompletableFuture<>(); 
ScheduledExecutorService executorService = 
Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(() -> 
{
try
{
throw new RuntimeException("My exception.");
}
catch(Exception e)
{
delayed.completeExceptionally(e);
}
}, 1000L, 150L, TimeUnit.MILLISECONDS));
delayed.whenCompleteAsync((r, t) -> {
if (t != null)
{
throw new RuntimeException(t);
}
});
}

我正试图找出我将在executorService中发现的异常。但实际情况是,异常被抛出到被捕获的try块中,并且CompletableFuturecompletedExceptionally。然后重新引发异常。我希望通过这种方式我能够打破这个例外。

但不幸的是,事实并非如此。delayed抛出异常,但它没有冒泡。除此之外,由于某些原因,异常循环紧接着开始。这就是try不断抛出异常,catch不断捕捉,但当然completableFuture已经完成了,所以它不会变成那样。

问题是,我们如何处理和冒泡这个例外?

这对我有效:

public void restart() throws Exception {
CompletableFuture<?> delayed = new CompletableFuture<>();
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(() -> {
try {
throw new RuntimeException("My exception.");
} catch(Exception e) {
delayed.completeExceptionally(e);
}
}, 1000L, 150L, TimeUnit.MILLISECONDS);
try {
delayed.get();
} catch (ExecutionException e) {
throw (Exception) e.getCause();
}
}

在这个修改后的代码中,我们在延迟的CompletableFuture上调用get()方法,该方法将阻塞直到CompletableFuture完成。如果CompletableFuture异常完成,则get()抛出一个ExecutionException,并将原始异常作为其原因。然后,我们提取原因并将其重新列为Exception。通过这种方式,异常被冒泡到restart()方法中,并且可以进行适当的处理。

但是,如果我们想在不使用阻塞get调用的情况下实现它,我们可以使用回调Consumer<Throwable> callback,如果exeption抛出,则使用callback.accept(e);,如以下片段所示:

public static void main(String[] args) {
restart((t) -> System.out.println("Exception occurred: " + t.getMessage()));
}
public static void restart(Consumer<Throwable> callback) {
CompletableFuture.runAsync(() -> {
try {
// Code that may throw an exception goes here
throw new RuntimeException("My exception.");
} catch (Exception e) {
callback.accept(e);
}
});
}

相关内容

  • 没有找到相关文章

最新更新