Python 官方文档:入门教程 => 点击学习
一、提出问题 最近有一位朋友问了我这样一个问题,问题的截图如下: 这个问题问的相对比较笼统,我来稍微详细的描述下:主线程向线程池提交了一个任务,如果执行这个任务过程中发生了异常,
最近有一位朋友问了我这样一个问题,问题的截图如下:
这个问题问的相对比较笼统,我来稍微详细的描述下:主线程向线程池提交了一个任务,如果执行这个任务过程中发生了异常,如何让主线程捕获到该异常并且进行事务的回滚。
先来看看基础,下图体现了两种线程的运行方式,
对于上文中提出的问题,一定是第二种才能解决主线程能够捕获子线程执行过程中发生的异常。这里就不得不提一个面试题,实现线程的两个接口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;
}
下面是我写的一个测试用例,在这里它代表了主线程的程序执行流程
@Test
void 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方法。
Future.get()方法达到了阻塞主线程的目的,从而可以判断子线程任务的执行结果,并且get方法可以抛出异常。
V get() throws InterruptedException, ExecutionException;
下面这张图是上面的测试用例程序程序e.printStackTrace();
的效果,从图中可以看到两个Exception异常,一个是我们在子线程任务中以模拟的方式主动抛出的空指针异常,另一个由于空指针引发的get方法抛出的ExecutionException。
上文中大家已经看到我们通过
那么既然我们已经可以在主线程内感知或catch子线程的异常信息了,下一步主线程的事务回滚是不是就太简单了?
conn.rollback()
实现事务的回滚@Transactional
注解就可以了。到此这篇关于详解Java子线程异常时主线程事务如何回滚的文章就介绍到这了,更多相关Java 事务的回滚内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: 详解Java子线程异常时主线程事务如何回滚
本文链接: https://www.lsjlt.com/news/142021.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0