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()方法进行转换。