1、多线程中怎么捕获子线程中的异常?
这个问题大家会经常遇到,子线程在执行过程中抛出了异常,但是主线程并没有捕获到。解决方案也非常简单,就是在将异常捕获,并在主线程抛出,具体代码如下:
ThreadOperation threadOperation= new ThreadOperation();
Thread innerThread = new Thread(threadOperation);
innerThread.setUncaughtExceptionHandler(new ExceptionHandle());
innerThread.start();
可以通过上面四行代码来捕获到异常
2、多线程中怎么将子线程的方法体也用事务管理起来?
我们知道在事务内,另起一个线程,这个子线程并不受事务管理,因为只有spring托管的bean才会去管理事务,自己new出来的不管理事务。
比如我们要用多线程处理一个添加功能,往若干子表插入数据,我们希望这个添加方法失败的时候,可以进行事务控制回滚。如果我们在主线程上面直接使用注解@Transactional来控制事务是不好使的,我们需要控制的是子线程的事务,解决方案如下:
1)在A类中执行方法体,该方法体是受事务控制的,在该方法中我们新建一个子线程,去处理前面提到的往若干子表添加数据的任务;
2)此时我们在子线程的run方法里面调用的添加方法不要放在当前类里面,放在其他的类B里面实现;
- 在B类上添加注解@Component、@Transactional
- 在A类的子线程run方法中通过B类进行调用,这样就可以将子线程的方法通过事务来控制了。
3、@Transaction 和 Synchronized作用范围不当引起的脏读原因?
比如我们对method添加注解@Transaction进行事务控制,该方法中使用了多线程,对主线程a用了Synchronized 锁,b线程在做幂等校验的时候 读到了a线程处理的数据,但是由于整个事务还没有提交,所以出现了脏读。
解决方案1:将事务包裹在Synchronized 锁里面,就是在method方法上加上同步锁,在主线程a上执行的代码块抽出一个方法,并添加@Transaction注解,在子线程b中,new一个子线程后,重写afterCommit()方法,意思就是保住b线程的执行,是在a线程执行完并提交事务后,再执行的,这样就避免了脏读。
这3个问题其实处理起来非常简单,并没有写代码示例,主要记录一下平时遇到问题的解决思路,后续有时间补充,望见谅。
网友评论