当异步方法中的一个发生异常时终止所有线程

Posted

技术标签:

【中文标题】当异步方法中的一个发生异常时终止所有线程【英文标题】:Terminate all threads when exception occurs for one in an asynchronous method 【发布时间】:2020-10-05 19:36:12 【问题描述】:

如果在异步方法中的任何一个线程中遇到异常,是否可以立即中断所有其他线程的执行?该方法返回一个 completableFuture 对象。

    @Async("asyncTaskExecutor")
public CompletableFuture<String> updateOp(String department, List<Student> student, Boolean flag)

....
....
return departmentId;

这个异步方法被另一个服务类方法调用:

    public List<String> updateDepartments

....
....
try 
List<CompletableFuture<String>> futures = new ArrayList<>();
for (String department: departmentList) 
            CompletableFuture<String> departmentId= updateAsyncService.updateOp(department,
                    studentList, statusFlag);
            futures.add(departmentId);
        
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).join();
        for (CompletableFuture<String> future : futures) 
            departmentIdList.add(future.get());
        
 catch (Exception e) 
        logger.error(e);
         
return departmentIdList;

上述方法对各个部门异步运行。现在,如果任何部门的更新操作失败(运行 updateOp 时任何线程发生异常),我希望所有线程停止执行。

另外,在这种情况下,我将如何检索成功运行 updateOp 的部门,以获取这些部门 ID 的列表。 提前感谢您的帮助。

【问题讨论】:

你解决了吗? 【参考方案1】:

不确定 join() 是否真的可以在这里实现您的目的。尝试像下面的代码 sn-p 一样处理它。祝你好运!

            boolean flag = false;
            for (Future<Void> future : futureSet ) 
                try 
                    future.get();
                 catch (InterruptedException e) 
                    System.out.println("Interrupted");
                 catch (ExecutionException e) 
                    System.out.println("Exception thrown from the thread");
                    flag = true;
                    break;
                
            

            if(flag) 
                for (Future<Void> future : futureSet) 
                    future.cancel(true);
                
            

【讨论】:

这种方法不起作用,因为它仍然让线程继续执行(在线程上为 future.cancel(true) 返回 FALSE)。它只会阻止线程进一步执行任何新任务。 另外,我们能否在这个异步方法中检索执行器对象

以上是关于当异步方法中的一个发生异常时终止所有线程的主要内容,如果未能解决你的问题,请参考以下文章

线程操作之终止线程

如何停止线程?

Java并发程序设计线程池之异常终止和正常关闭

JVM 终止时会发生啥?

线程任务异常终止问题

多线程与计划任务