当前位置:   article > 正文

已解决java.util.concurrent.CancellationException异常的正确解决方法,亲测有效!!!

java.util.concurrent.cancellationexception

已解决java.util.concurrent.CancellationException异常的正确解决方法,亲测有效!!!

文章目录

问题分析

报错原因

解决思路

解决方法

总结


java.util.concurrent.CancellationException是 Java 并发编程中常见的异常,常出现在Future任务取消、线程池关闭、CompletableFuture等场景中。本文将详细分析此问题并给出解决方法。

问题分析

我们先来看一个出现CancellationException的例子:

  1. ExecutorService executor = Executors.newSingleThreadExecutor();
  2. Future<String> future = executor.submit(() -> {
  3. Thread.sleep(1000);
  4. return "Task Completed";
  5. });
  6. future.cancel(true); // 取消任务
  7. System.out.println(future.get()); // 抛出 java.util.concurrent.CancellationException

在这个例子中,我们创建了一个任务并提交给ExecutorService执行。然后我们调用future.cancel(true)取消这个任务,在尝试获取任务结果时,就会抛出CancellationException。

报错原因

从代码中可以看出,CancellationException通常由于以下几种原因引起:

  1. 调用了Future的cancel方法,取消了一个尚未完成的任务。
  2. 在一个已经被取消的Future对象上调用get()方法。
  3. 当ExecutorService关闭时,还有尚未开始的任务。

这样做会使正在运行的线程被中断,如果你试图获取结果,那么就会抛出CancellationException。

 

解决思路

对于CancellationException的处理,我们需要根据具体情况采取不同的策略:

  1. 如果是由于任务被取消导致的异常,我们应该检查我们的代码,确保我们在取消任务后不再调用Future.get()方法。
  2. 如果是由于ExecutorService关闭导致的异常,我们应该确保在关闭ExecutorService时,所有已提交的任务都已经完成。

 

解决方法

针对以上各种情况,我们可以采取以下几种策略来处理CancellationException:

  1. 捕获并处理CancellationException。当我们调用Future.get()时,我们应该预期可能会抛出CancellationException,并编写相应的错误处理代码。
    1. try {
    2. future.get();
    3. } catch (CancellationException e) {
    4. // handle cancellation scenario
    5. }
  2. 在取消任务之前,检查任务是否已经完成。只有当任务仍在运行时,我们才应该尝试取消它。
    1. if (!future.isDone()) {
    2. future.cancel(true);
    3. }
  3. 在关闭ExecutorService之前,等待所有任务完成。这可以通过调用ExecutorService.awaitTermination()方法实现。
    1. executor.shutdown();
    2. try {
    3. if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
    4. executor.shutdownNow();
    5. }
    6. } catch (InterruptedException e) {
    7. executor.shutdownNow();
    8. }
  4. 使用CompletableFuture而非原生Future。CompletableFuture提供了更灵活的异常处理机制,能有效消除CancellationException。
    1. CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    2. // some long running task
    3. });
    4. // 优雅地处理取消
    5. future.exceptionally(ex -> {
    6. if (ex instanceof CancellationException) {
    7. return "Task Cancelled";
    8. }
    9. return "Unexpected error";
    10. });

总结

解决java.util.concurrent.CancellationException的关键是理解它的引发原因,并在代码中合理地处理任务取消和线程池关闭的情况。希望本文能帮助读者更好地理解并解决这个问题。

 以上是此问题报错原因的解决方法,欢迎评论区留言讨论是否能解决,如果本文对你有帮助 欢迎 关注 、点赞 、收藏 、评论, 博主才有动力持续记录遇到的问题!!!

博主v:XiaoMing_Java

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/462594
推荐阅读
相关标签