java常见异常问题整理(一)

1、线程池(coreSize=0,submit方法)

coreSize的问题 

代码:

new ThreadPoolExecutor(0, 50, 60,TimeUnit.SECONDS, new ArrayBlockingQueue(1000));

问题:发到线上后,发现CPU莫名其妙多次100%。

原因:自定义线程池coreSize不能为0,否则该线程池永远只有一条线程在跑,数据量大时扛不住

submit方法的问题

代码:

threadPool.submit(() ->  throw new RunTimeException() );

问题:在submit方法方法中如果出现了异常,日志并没有打印异常堆栈信息。

原因:submit方法在执行过程中出现了异常也不会主动抛出,需要使用Future捕获异常;而execute方法执行过程中,若有异常会直接抛出

2、SimpleDateFormat线程不安全

原因:SimpleDateFormat的parse方法,会用到父类DateFormat中的成员变量:

protected Calendar calendar;

多线程共享一个变量,所以线程不安全。

解决:使用Java8新的日期类 LocalDateTime 进行日期和字符串之间的转换。

3、Spring事务机制

问题:被 @Transactional 注解的方法,如果出现了异常数据库没有进行回滚操作。

原因:异常只有最终抛到事务拦截层,才会触发回滚机制,但中途如果被try-catch了,不会生效。事务Aop的order貌似都是0,这样的话是“包”在AOP集最外层的,所以仅靠 @Transactional 注解是无效的,必须在业务方法中手动回滚。

解决:在 catch 异常里进行手动回滚。

try{
    ......
}catch(Exception e){
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}

4、Spring自带拷贝

问题:BeanUtils.copyProperties在拷贝的时候出现了转换异常

原因:Integer -> int 拷贝会报错,包装类转基本类型的时候会导致出现异常错误(不会自带进行拆装包)。

解决:建议减少使用 BeanUtils.copyProperties 方法,如果需要注意类的前后字段属性一致。

5、BigDecimal的坑

问题:double 转 BigDecimal 的时候,如果直接使用new BigDecimal 方法会导致出现无限小数。

解决:使用 BigDecimal.valueOf()方法进行转换。

猜你喜欢

转载自blog.csdn.net/baidu_38083619/article/details/89739109