文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java子线程任务异常和主线程事务回滚问题怎么解决

2023-06-30 12:27

关注

这篇文章主要介绍了Java子线程任务异常和主线程事务回滚问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java子线程任务异常和主线程事务回滚问题怎么解决文章都会有所收获,下面我们一起来看看吧。

Java子线程任务异常和主线程事务回滚问题怎么解决

一、提出问题

主线程向线程池提交了一个任务,如果执行这个任务过程中发生了异常,如何让主线程捕获到该异常并且进行事务的回滚

二、主线程与子线程

先来看看基础,下图体现了两种线程的运行方式,

Java子线程任务异常和主线程事务回滚问题怎么解决

对于上文中提出的问题,一定是第二种才能解决主线程能够捕获子线程执行过程中发生的异常。这里就不得不提一个面试题,实现线程的两个接口Callable与Runnable之间的区别:

public interface Callable<V> {    V call() throws Exception;}
public interface Runnable {    public abstract void run();}

可以看到call方法带返回值,run方法没有返回值。另外call方法可以抛出异常,run方法不可以。很明显,我们为了要捕获或得知子线程的运行结果,或者运行异常,都应该通过Callable接口来实现。

这里我们写一个ExpSubThread类(子线程异常模拟类),实现Callable接口,不做过多的动作,直接抛出一个空指针异常。

public class ExpSubThread implements Callable {    @Override    public Object call() throws Exception {        throw new NullPointerException();    }}

三、线程池

在面临线程任务时,通常我们会预先建立一个线程池,线程池是预先规划好的n个线程资源的集合。它的好处在于:

常用的线程池有两种,一种是JDK自带的,一种是Spring线程池,在Spring环境下后者常常被使用,二者大同小异。这里我们使用Spring API来构建一个线程池。

public ThreadPoolTaskExecutor getThreadPool(){        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();        executor.setMaxPoolSize(100);  //线程池最大线程数        executor.setCorePoolSize(50);//线程池核心线程数        executor.setQueueCapacity(50);//任务队列的大小        executor.setThreadNamePrefix("test_"); //线程前缀名        executor.initialize(); //线程初始化        return executor;}

四、异常的捕获

下面是我写的一个测试用例,在这里它代表了主线程的程序执行流程

@Testvoid subThreadExceptionTest() {        try{            //新建子线程对象            ExpSubThread expSubThread = new ExpSubThread();            //构建线程池            ThreadPoolTaskExecutor executor = getThreadPool();            //提交子线程任务,submit方法            Future future = executor.submit(expSubThread);            //在这里可以做主线程的业务其他流程操作            //阻塞等待子线程的执行结果            Object obj = future.get();          }catch (Exception e){            e.printStackTrace();            //事务回滚        }}

这里需要注意的是使用submit方法提交子线程任务到线程池内执行。ThreadPoolTaskExecutor有两种执行线程任务的方法,一种是execute方法,一种是submit方法。

Java子线程任务异常和主线程事务回滚问题怎么解决

Future.get()方法达到了阻塞主线程的目的,从而可以判断子线程任务的执行结果,并且get方法可以抛出异常。

    V get() throws InterruptedException, ExecutionException;

下面这张图是上面的测试用例程序程序e.printStackTrace();的效果,从图中可以看到两个Exception异常,一个是我们在子线程任务中以模拟的方式主动抛出的空指针异常,另一个由于空指针引发的get方法抛出的ExecutionException。

Java子线程任务异常和主线程事务回滚问题怎么解决

五、事务的回滚

上文中大家已经看到我们通过

那么既然我们已经可以在主线程内感知或catch子线程的异常信息了,下一步主线程的事务回滚是不是就太简单了?

关于“Java子线程任务异常和主线程事务回滚问题怎么解决”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Java子线程任务异常和主线程事务回滚问题怎么解决”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯